我在 Angular 应用程序中使用信号。
我正在使用这样的
computed
信号,我自愿抛出异常来测试在“计算”信号中抛出异常时会发生什么,我的真实代码要复杂得多。
public test: Signal<string> = computed(() => {
throw new Error(`Testing throwing exception`);
return 'foo';
});
<p>{{ test() }}</p>
我使用 bugsnag 来报告意外异常,并且向 bugsnag 报告了多次而不是一次。
我找到的一个解决方案是在我的计算函数中添加一个 try catch 并手动向 bugsnag 报告,如下所示:
public test: Signal<string> = computed(() => {
try {
throw new Error(`Testing throwing exception`);
return 'foo';
} catch (error) {
Bugsnag.notify(error as NotifiableError);
return '';
}
});
但是有没有更好的方法来处理这个用例?我猜想在“计算信号”中处理异常是很常见的
当计算函数中发生错误时,错误(与正常使用中的值一样)会被记住。因此,下次读取计算信号时,如果依赖关系没有改变,则计算函数将不会重新执行,并且将再次抛出记忆错误。
您可以使用此示例检查此行为:
@Component({
selector: 'app-root',
standalone: true,
template: `
<button type="button" (click)="handleClick()">
Click me
</button>
{{vComputed()}}
`,
})
export class App {
handleClick() {
console.log('clicked');
}
vComputed = computed(() => {
console.log('execution of computed function');
throw Error('error');
});
}
消息
execution of computed function
仅打印一次(因为信号没有依赖性,因此计算函数永远不会重新执行),每次读取计算信号时都会抛出错误(每次单击按钮,因为它会触发更改检测并刷新视图。
因此,我看到了两种处理计算信号错误的选项:
@Component({
selector: 'app-root',
standalone: true,
template: `
<button type="button" (click)="handleClick()">
Click me
</button>
{{getValue()}}
`,
})
export class App {
...
vComputed = computed<number>(() => {
console.log('execution of computed function');
try {
throw Error('error');
} catch(e) {
return 0;
}
});
@Component({
selector: 'app-root',
standalone: true,
template: `
<button type="button" (click)="handleClick()">
Click me
</button>
{{getValue()}}
`,
})
export class App {
...
getValue() {
try {
return vComputed();
} catch (e) {
return 0;
}
}
两种解决方案之间存在细微差别,在第二个解决方案中,catch 块将在每次渲染时重新执行(每次调用
getValue
函数时),而在第一个解决方案中,回退值会被记忆,因此catch 块仅执行一次。