From 2a223288d498aea984925824a0531e8e813bd1ff Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 19 Sep 2024 13:43:47 +0200 Subject: [PATCH] [IMP] make set of timeout-able hooks (and their timeouts) clearer by using a const map Also unnest the handling of `result` via guard clauses, and generate messages as close as possible to use site, keeping the error construction itself where it currently is as the goal is specifically to point back to the *definition* site for the hook function. --- src/runtime/lifecycle_hooks.ts | 54 +++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/src/runtime/lifecycle_hooks.ts b/src/runtime/lifecycle_hooks.ts index fa62b308..104c77df 100644 --- a/src/runtime/lifecycle_hooks.ts +++ b/src/runtime/lifecycle_hooks.ts @@ -3,42 +3,50 @@ import { nodeErrorHandlers } from "./error_handling"; import { OwlError } from "../common/owl_error"; const TIMEOUT = Symbol("timeout"); +const HOOK_TIMEOUT: { [key: string]: number } = { + onWillStart: 3000, + onWillUpdateProps: 3000, +}; function wrapError(fn: (...args: any[]) => any, hookName: string) { - const error = new OwlError(`The following error occurred in ${hookName}: `) as Error & { + const error = new OwlError() as Error & { cause: any; }; - const timeoutError = new OwlError(`${hookName}'s promise hasn't resolved after 3 seconds`); + const timeoutError = new OwlError(); const node = getCurrent(); return (...args: any[]) => { const onError = (cause: any) => { error.cause = cause; - if (cause instanceof Error) { - error.message += `"${cause.message}"`; - } else { - error.message = `Something that is not an Error was thrown in ${hookName} (see this Error's "cause" property)`; - } + error.message = + cause instanceof Error + ? `The following error occurred in ${hookName}: "${cause.message}"` + : `Something that is not an Error was thrown in ${hookName} (see this Error's "cause" property)`; throw error; }; + let result; try { - const result = fn(...args); - if (result instanceof Promise) { - if (hookName === "onWillStart" || hookName === "onWillUpdateProps") { - const fiber = node.fiber; - Promise.race([ - result.catch(() => {}), - new Promise((resolve) => setTimeout(() => resolve(TIMEOUT), 3000)), - ]).then((res) => { - if (res === TIMEOUT && node.fiber === fiber && node.status <= 2) { - console.log(timeoutError); - } - }); - } - return result.catch(onError); - } - return result; + result = fn(...args); } catch (cause) { onError(cause); } + if (!(result instanceof Promise)) { + return result; + } + const timeout = HOOK_TIMEOUT[hookName]; + if (timeout) { + const fiber = node.fiber; + Promise.race([ + result.catch(() => {}), + new Promise((resolve) => setTimeout(() => resolve(TIMEOUT), timeout)), + ]).then((res) => { + if (res === TIMEOUT && node.fiber === fiber && node.status <= 2) { + timeoutError.message = `${hookName}'s promise hasn't resolved after ${ + timeout / 1000 + } seconds`; + console.log(timeoutError); + } + }); + } + return result.catch(onError); }; }