【问题标题】:Global Error handling with Observable.toPromise()使用 Observable.toPromise() 处理全局错误
【发布时间】:2019-05-21 00:16:57
【问题描述】:

嗨,我正在使用 Angular 5,我正在为它编写一个全局处理程序,如下所示。

@Injectable()
export class ErrorsHandler implements ErrorHandler {
  constructor(
    private injector: Injector,
  ) { }


  handleError(error: Error | HttpErrorResponse) {
    const router = this.injector.get(Router);
    const zone = this.injector.get(NgZone);
    console.log('Here')
    console.log(error)

    if (error instanceof HttpErrorResponse) {

      // Client Error Happend
      zone.run(() => router.navigate(['/error'], { queryParams: { error: JSON.stringify(error) } }))

    } else {
      // Log the error anyway
      router.navigate(['/error'], { queryParams: { error: JSON.stringify({ message: 'Failed' }) } });
    }
  }
}

在 Observable 世界中一切正常,即如果我执行失败的 http 调用,如下所示

fireServerError() {
    this.httpService
            .get('https://jsonplaceholder.typicode.com/1')
            .subscribe(data => console.log('Data: ', data));
  }

如果服务器调用失败,我会正确地得到一个错误对象,如控制台图像所示

但是,如果我使用 toPromise() 将其更改为承诺,而不是像下面这样

fireServerError() {
    this.httpService
            .get('https://jsonplaceholder.typicode.com/1')
            .toPromise();
  }

我得到以下字符串堆栈跟踪而不是错误对象本身

我做错了什么。在未处理的承诺拒绝的情况下如何抛出/获取错误对象。请帮忙。我被卡住了;

请找到stackblitz链接Here

【问题讨论】:

  • 您是否尝试过类似以下的操作:fireServerError() { this.httpService.get('https://jsonplaceholder.typicode.com/1').toPromise().catch(err => console.error(err)); }
  • 是的,但我不想吞下 catch 块中的错误,而是重新抛出它,以便全局错误处理程序处理它。我附上了 stackblitz 链接来解决这个问题。
  • 如果在 catch 中,您确实返回了一个新的已解决承诺,错误为 Promise.resolve(err)?
  • 再次被吞没,除非你再次抛出它以便全局处理程序可以处理它。

标签: javascript angular angular5


【解决方案1】:

一旦你使用.toPromise(),你实际上是把行为放到不同的执行上下文中(阅读ECMAScript 10.4),这意味着错误必须在新的执行上下文中/周围处理,而不是让它们在Angular中冒泡正如你所期待的那样。

我不能说我完全遵循您的示例代码(fireServerError 是否总是应该通过 HTTP 调用抛出错误?),但您似乎想尝试在没有本地错误处理的情况下执行承诺,而是从承诺冒泡到角度错误处理的任何错误。我不确定我是否会推荐,我认为在本地处理 promise 错误是最佳实践(即在创建 promise 时使用 Promise.prototype.catchtry/await/catch block)。

话虽如此,错误处理当然是一个复杂的话题,如果您一心只想在全局级别处理所有错误,那么您可以尝试使用全局窗口事件处理程序来捕获所有未处理的 promise rejections 并处理它们那里:

window.addEventListener("unhandledrejection", event => {
  event.preventDefault(); // prevent the default promise rejection behavior
  console.error(event); // do whatever you want with the error
}, false);

MDN guide on promises 也可能有助于解决一些问题,希望对您有所帮助!

【讨论】:

    猜你喜欢
    • 2015-08-04
    • 1970-01-01
    • 2023-04-01
    • 2010-11-25
    • 1970-01-01
    • 2013-03-06
    • 2012-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多