Angular组件内抛出错误如何被全局ErrorHandler正确处理?
问题原因
你在组件的error回调中使用throw new Error(error)时,Error构造函数会自动将传入的参数转为字符串,原始的Http错误对象(包含status属性的HttpErrorResponse实例)调用toString()后就会变成[Object object],全局错误处理器拿到的新Error实例自然丢失了原始的status等属性。
解决方案
方案1:直接抛出原始错误(推荐)
不需要额外封装Error,处理完组件自有逻辑后直接抛出原始错误对象即可,全局处理器就能拿到完整的原始错误信息:
updateQuantity(i: number): void { this.CartService.update(i).subscribe(data => { // 业务逻辑 }, error => { console.log('Some text should be shown when the method receives the error'); // 直接抛出原始错误,不要new Error包装 throw error; }) }
方案2:封装错误时保留原始错误引用
如果你需要自定义错误信息,可以用ES2022支持的cause参数挂载原始错误,同时调整全局错误处理器的读取逻辑:
- 组件内抛出错误的写法:
error => { console.log('组件自有错误逻辑'); // 第二个参数传入配置对象,将原始错误挂载到cause属性 throw new Error('组件层自定义错误提示', { cause: error }); }
- 全局错误处理器调整读取逻辑:
@Injectable() export class MyErrorHandler implements ErrorHandler { constructor( private UserService: UserService, ) { } handleError(error) { // 优先读取cause里的原始错误,不存在就用当前error const originError = error.cause ?? error; if (originError?.status === 401) { this.UserService.signOut(); } } }
补充说明
RxJS的subscribe默认行为是:如果没有传入error回调,流产生的错误会自动向上冒泡到全局ErrorHandler;如果传入了error回调,错误就会被回调捕获,只有手动抛出才会继续传递到全局错误处理器,这是你添加error回调后需要手动抛错的原因。
内容的提问来源于stack exchange,提问作者mr_blond
相关产品推荐
相关产品推荐

