[REF] component: move error handling into the fiber

This commit is contained in:
Géry Debongnie
2019-10-26 10:27:56 +02:00
committed by Aaron Bohy
parent 2aa705f5c8
commit 2c563ee380
2 changed files with 34 additions and 40 deletions
+6 -39
View File
@@ -262,8 +262,11 @@ export class Component<T extends Env, Props extends {}> {
/**
* catchError is a method called whenever some error happens in the rendering or
* lifecycle hooks of a child.
*
* It needs to be implemented by a component that is designed to handle the
* error properly.
*/
catchError(error: Error): void {}
catchError?(error?: Error):void;
//--------------------------------------------------------------------------
// Public
@@ -561,7 +564,7 @@ export class Component<T extends Env, Props extends {}> {
try {
await Promise.all([this.willStart(), this.__owl__.willStartCB && this.__owl__.willStartCB()]);
} catch (e) {
errorHandler(e, fiber);
fiber.handleError(e);
fiber.vnode = h("div"); // -> we render this div at the end
return Promise.resolve();
}
@@ -586,7 +589,7 @@ export class Component<T extends Env, Props extends {}> {
});
} catch (e) {
vnode = __owl__.vnode || h("div");
errorHandler(e, fiber);
fiber.handleError(e);
}
fiber.vnode = vnode;
if (__owl__.observer) {
@@ -650,39 +653,3 @@ export class Component<T extends Env, Props extends {}> {
return <Props>props;
}
}
//------------------------------------------------------------------------------
// Error handling
//------------------------------------------------------------------------------
Fiber.prototype.handleError = function(error) {
errorHandler(error, this);
};
/**
* This is the global error handler for errors occurring in Owl main lifecycle
* methods. Caught errors are triggered on the QWeb instance, and are
* potentially given to some parent component which implements `catchError`.
*
* If there are no such component, we destroy everything. This is better than
* being in a corrupted state.
*/
function errorHandler(error: Error, fiber: Fiber) {
let canCatch = false;
let component = fiber.component;
let qweb = component.env.qweb;
let root = component;
while (component && !(canCatch = component.catchError !== Component.prototype.catchError)) {
root = component;
component = component.__owl__.parent!;
}
console.error(error);
qweb.trigger("error", error);
if (canCatch) {
setTimeout(() => {
component.catchError(error);
});
} else {
root.destroy();
}
}
+28 -1
View File
@@ -195,5 +195,32 @@ export class Fiber {
});
}
handleError(e: Error) {}
/**
* This is the global error handler for errors occurring in Owl main lifecycle
* methods. Caught errors are triggered on the QWeb instance, and are
* potentially given to some parent component which implements `catchError`.
*
* If there are no such component, we destroy everything. This is better than
* being in a corrupted state.
*/
handleError(error: Error) {
let canCatch = false;
let component = this.component;
let qweb = component.env.qweb;
let root = component;
while (component && !(canCatch = !!component.catchError)) {
root = component;
component = component.__owl__.parent!;
}
console.error(error);
qweb.trigger("error", error);
if (canCatch) {
setTimeout(() => {
component.catchError!(error);
});
} else {
root.destroy();
}
}
}