【问题标题】:Angular ErrorHandler and HttpErrorResponseAngular ErrorHandler 和 HttpErrorResponse
【发布时间】:2020-06-26 14:04:03
【问题描述】:

今天我决定为我的 Angular 应用程序更多地研究一些集中式错误报告。我使用了 Michael Karén (https://medium.com/angular-in-depth/expecting-the-unexpected-best-practices-for-error-handling-in-angular-21c3662ef9e4) 在 Medium 上的精彩文章,解释了如何处理客户端和服务器端问题并记录它们。

在我的示例项目中,我有一个非常简单的拦截器:

export class HttpInterceptor implements NgHttpInterceptor {
  constructor(
    private auth : AuthService
  ) { }
  intercept(request : HttpRequest<any>, next : HttpHandler) : Observable<HttpEvent<any>> {
    return next.handle(request)
      .pipe(
        retry(1),
        catchError((error : HttpErrorResponse) => {
          return throwError(error);
        })
      );
  }
}

还有非常简单的ErrorHandler:

@Injectable()
export class AppErrorHandler implements ErrorHandler {
  constructor(
    private readonly injector : Injector
  ) { }
  handleError(error : Error | HttpErrorResponse) {
    /** injectables */
    const errorService = this.injector.get(ErrorService);
    const loggingService = this.injector.get(LoggingService);
    /** initialize empty variables */
    let message : string;
    let stackTrace : string;
    if (error instanceof HttpErrorResponse) {
      console.log('server');
    } else {
      console.log('client');
    }
  }
}

是的,到目前为止,它还没有真正记录日志,但这不是问题。然而,我注意到的是,当使用 Angular 的 HttpClient 时,或者 1) 使用 toPromise() 方法而不是订阅,或者 2) 在响应时订阅错误,错误处理程序会说 error instanceof HttpErrorResponse 是错误的。所以..

这将正确记录“服务器”:

this.httpClient.get('foo').subscribe()

这将错误地记录“客户端”:

this.httpClient.get('foo').subscribe(
  data => console.log,
  error => console.error
)

这也会错误地记录“客户端”:

await this.httpClient.get('foo').toPromise()

由于我完全无法理解这里到底发生了什么以及为什么会出现问题,请有人帮我正确报告 HTTP 错误吗?我正在考虑在 HttpInterceptor 中记录这些错误,但是当抛出它们时,ErrorHandler 会再次将它们记录为客户端错误。

我为什么要使用回调 使用回调主要是因为所有这些调用都在各自的服务中。例如,用户服务从端点获取数据,对数据做一些事情,然后解决一个承诺(或者完成观察者,不管是什么)

编辑:

我创建了一个 StackBlitz 示例来说明问题:https://stackblitz.com/edit/angular-ivy-gjtxk2

【问题讨论】:

    标签: angular angular-http-interceptors angular-errorhandler


    【解决方案1】:

    我已经检查了您的 StackBlitz 样本。如果您在处理 HTTP-Broken 2 中的错误时遇到问题,请修改您的代码以捕获错误并将其扔给 GlobalHandler -

      httpBroken2() {
        this.httpClient.get(this.randomUrl()).pipe(catchError((errors: HttpErrorResponse) => {
          // anything you want to do (i.e. modify error)
          return throwError(errors);
        })).subscribe(
          (data) => {
            alert(data);
          }
        )
      }
    

    【讨论】:

    • 有点太健谈了,我希望避免整个再次抛出它,但我想这很容易:) 谢谢!
    • 欢迎 :)。如果您不想在发生错误时执行任何操作,则不需要 catchError。它会在 AppErrorHandler 中自动处理。
    • 对,所以在 RXJS 中,当在 observable 上使用 catch 时,它显然可以防止错误冒泡(比如 try{..}catch(){..} 块。知道这一点非常有用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-28
    • 2019-07-29
    • 2018-12-02
    • 1970-01-01
    • 2019-12-03
    • 2019-01-06
    • 2018-06-27
    相关资源
    最近更新 更多