mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[REF] component: move error handling into the fiber
This commit is contained in:
committed by
Aaron Bohy
parent
2aa705f5c8
commit
2c563ee380
@@ -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
|
* catchError is a method called whenever some error happens in the rendering or
|
||||||
* lifecycle hooks of a child.
|
* 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
|
// Public
|
||||||
@@ -561,7 +564,7 @@ export class Component<T extends Env, Props extends {}> {
|
|||||||
try {
|
try {
|
||||||
await Promise.all([this.willStart(), this.__owl__.willStartCB && this.__owl__.willStartCB()]);
|
await Promise.all([this.willStart(), this.__owl__.willStartCB && this.__owl__.willStartCB()]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
errorHandler(e, fiber);
|
fiber.handleError(e);
|
||||||
fiber.vnode = h("div"); // -> we render this div at the end
|
fiber.vnode = h("div"); // -> we render this div at the end
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
@@ -586,7 +589,7 @@ export class Component<T extends Env, Props extends {}> {
|
|||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
vnode = __owl__.vnode || h("div");
|
vnode = __owl__.vnode || h("div");
|
||||||
errorHandler(e, fiber);
|
fiber.handleError(e);
|
||||||
}
|
}
|
||||||
fiber.vnode = vnode;
|
fiber.vnode = vnode;
|
||||||
if (__owl__.observer) {
|
if (__owl__.observer) {
|
||||||
@@ -650,39 +653,3 @@ export class Component<T extends Env, Props extends {}> {
|
|||||||
return <Props>props;
|
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
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user