首页 > 解决方案 > 如何从 HttpErrorResponse 获取请求的正文/内容?[角度错误处理程序]

问题描述

假设我向post服务器发送了一个创建用户的请求。如果服务器响应错误,我想从ErrorHandler. 这样做的原因是,例如,当“创建用户”失败时,我想显示一个通知,其中包含从表单中获取的一些详细信息和一个按钮,用于将您重定向回相应的页面,并再次填充检索到的字段形式。

这就是我的ErrorHandler样子:

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

    handleError(error: Error | HttpErrorResponse) {
        const errorsService = this.injector.get(ErrorsService);
        const router = this.injector.get(Router);
        const zone = this.injector.get(NgZone);
        if (error instanceof HttpErrorResponse) {
            // Server error happened
            if (!navigator.onLine) {
                return console.log('No Internet Connection.');
            }
            else if (error.status === HttpStatus.UNAUTHORIZED) {
                console.log('ErrorsHandler handled HttpStatus Unauthorized. Navigating back to \'/login\' page.');
                zone.run(() => router.navigate(['/login']));
            }
            else {
                // Http Error
                //How do I get the form from here? I need it for user notification.
                return console.log('%c SERVER ERROR ', 'background: #222; color: #ff6961 ; font-size: 15px; border: 2px solid #ff6961;', error);
            }
        } else {
            // Client Error Happend
            // Send the error to the server and then
            // redirect the user to the page with all the info
            errorsService
                .log(error)
                .subscribe(errorWithContextInfo => {
                    router.navigate(['/error'], { queryParams: errorWithContextInfo });
                });
        }
    }
}

标签: angularerror-handlingangular-errorhandler

解决方案


我用拦截器对@GabrielLopez 的回答有所不同:

import {Injectable} from '@angular/core';
import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpResponse}
  from "@angular/common/http";
import {Observable, throwError} from "rxjs";
import {catchError, tap} from "rxjs/operators";

@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {

  intercept(req: HttpRequest<any>,
            next: HttpHandler):
        Observable<HttpEvent<any>> {
    return next.handle(req)
      .pipe(
        tap((ev: HttpEvent<any>) => {
          if (ev instanceof HttpResponse) {
            console.log(`processing response ${ev.status}`);
          }
        }),
        catchError(response => {
          console.log('Processing http error', response);
          if (response.error) {
            return throwError(response.error);
          } else if (response.message) {
            return throwError(response.message);
          } else {
            return throwError(response);
          }
        })
      );
  }
}

和加布里埃尔的回答一样,拦截器需要在 app.module.ts 中声明providers

@NgModule({
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: HttpErrorInterceptor,
      multi: true
    },
    ...

我对此不满意,因为这可能意味着 Angular HttpClient 错误处理过度设计。从 REST API 调用中获取错误应该不难。


推荐阅读