🦉 错误处理 🦉
概览
默认情况下,当 Owl 应用在渲染过程中发生错误时,我们会销毁整个应用。否则,无法保证组件树的状态是否仍然正确,可能已经彻底损坏,但用户却毫无察觉。
显然,直接销毁应用往往有些激进。因此,我们需要一个机制来处理渲染错误(以及生命周期钩子中的错误):这就是 onError
钩子。
核心思想是,onError
钩子注册一个函数,当错误发生时会被调用。这个函数需要处理该情况,通常通过更新一些状态并重新渲染自身,让应用可以恢复到正常状态。
错误管理
当使用了 onError
生命周期钩子时,所有来自子组件渲染过程或生命周期方法的错误都会被捕获,并交由 onError
方法处理。这样我们就能妥善应对错误,不至于让应用崩溃。
需要注意以下几点:
如果渲染过程中的错误未被捕获,Owl 将销毁整个应用。这是有意为之,因为 Owl 无法再保证状态的正确性。
来自事件处理函数的错误不会由
onError
或任何 Owl 内建机制处理。这部分错误需要应用开发者自己负责处理。如果一个错误处理器无法正确处理错误,它可以重新抛出错误,Owl 将向上查找下一个可以处理该错误的组件。
示例
下面是一个如何实现通用组件 ErrorBoundary
的例子。它会渲染其内容,若出现错误,则渲染备用内容。
js
class ErrorBoundary extends Component {
static template = xml`
<t t-if="state.error" t-slot="fallback">发生错误</t>
<t t-else="" t-slot="default"/>`;
setup() {
this.state = useState({ error: false });
onError(() => (this.state.error = true));
}
}
使用 ErrorBoundary
非常简单:
xml
<ErrorBoundary>
<SomeOtherComponent/>
<t t-set-slot="fallback">出现了某些特定错误</t>
</ErrorBoundary>
注意:需要确保备用 UI 本身不会抛出错误,否则可能会导致无限循环(更多关于 t-slot
指令的内容请参阅插槽页面)。