代码之家  ›  专栏  ›  技术社区  ›  Muhammed Ozdogan

角度HttpClient观测值默认误差函数

  •  2
  • Muhammed Ozdogan  · 技术社区  · 6 年前

    在后端,我创建了一个很好的异常机制,所以当请求失败时。服务器将向客户端发送一条很好的错误消息,其中包含一些错误代码。

    这样地:

    @Getter
    public class ErrorResponse {
    
        /**
         * Http Response status code
         */
        private final HttpStatus status;
    
        /**
         * General Error Message
         */
        private final String message;
    
        private final ErrorCode errorCode;
    
        private final Date timeStamp;
    ...
    }
    

    默认情况下,每次失败时,我都要向用户显示错误消息。

    我试着扩展 HttpClient

    public get<T>(endPoint: string, options?: IRequestOptions): Observable<T> {
        return this.http.get<T>(this.API + endPoint, options);
      }
    

    但它正在返回一个 Observable

    在这一页的大部分时间里,我都在做这样的事情

    this.client.post(WebUtils.RESOURCE_HOST + '/api' + '/actor/create', formData
        ).subscribe(
          () => this.onSuccessfulPost(),
          error => {
            this.snack.error(error.error.message);
          }
        );
    

    在很多页面上,我都在写同样的东西:

    error => {
                this.snack.error(error.error.message);
              }
    

    我看了这篇文章 about extending HttpClient.
    但这对我来说还不够,它只是定义了 default "API_HOST" 我想定义请求方法返回对象的默认错误函数,它们是可观察的。

    有没有像扩展一样操作“HttpClient请求方法”的返回对象?

    3 回复  |  直到 6 年前
        1
  •  3
  •   user4676340user4676340    6 年前

    你可以用新的 HTTPClient interceptors 是为这个而做的。

    下面是一个例子:

    export class ErrorHandlerService implements HttpInterceptor {
    
      intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next
          .handle(req)
          .catch((err: HttpErrorResponse) => {
              console.log('error');
              // Mandatory return statement
              return Observable.throw(err);
            }
          );
      }
    
    }
    

    在Angular执行的每个HTTP请求中,都会运行这个拦截器,并按照您告诉它的方式运行。在这种情况下,它会记录错误,但你可以让他做任何你想做的事。

        2
  •  1
  •   Marcel Cremer    6 年前

    我个人在集中错误处理方面所做的工作如下:

    在我的服务中,我用catchError截取http请求

    return this.httpClient .get(...) .pipe( catchError(this.handleError.bind(this) );

    错误处理(在我的例子中,日志记录依赖于HTTP返回状态和返回值)是在handleError方法中完成的,如下所示:

    `

    private handleError(error: any) {
        error = error || {};
        if (error.status == 401 || error == 401 || error == 'Unauthorized') {
          ...
          this.logout();
        } else if (error.status == 403 || error == 403 || error == 'Forbidden') {
          ...
        } else if ((error.status == 423 || error == 423) && error._body) {
          ...
        } else if (error.status == 500) {
          ...
        } else {
          return this.processUnknownError(error);
        }
        return _throw(error);
      }
    

    `

    我还声明了一个全局noop函数

    export function noop() {}

    所以我所有的服务消费者只打电话

    this.dataService.getFoo().subscribe((values) => { ... }, noop);

    也许这种尝试也适合你?

        3
  •  1
  •   Muhammed Ozdogan    6 年前

    多亏了trichetriche,如果你想用“HttpClient”进行集中的异常处理,这里是我的最终代码:

    1)创建拦截器:

    import {Injectable} from '@angular/core';
    import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
    import {Observable} from 'rxjs';
    import {catchError} from 'rxjs/operators';
    import {throwError} from 'rxjs';
    import {SnackService} from '../services/snack.service';
    
    @Injectable({
      providedIn: 'root'
    })
    export class HttpErrorHandlerService implements HttpInterceptor {
    
      constructor(private snack: SnackService) {
      }
    
      intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(req)
          .pipe(catchError(err => {
              this.snack.error(err.error.message);
              return throwError(err);
            }
          ));
      }
    
    }
    

    小吃是定制的 snackbar 然后我通知用户。

    2)提供拦截器:

    const HTTP_INTERCEPTOR_PROVIDERS = [
      {provide: HTTP_INTERCEPTORS, useClass: HttpErrorHandlerService, multi: true }
    ];
    

    将它添加到项目模块中,它可以是“ app.module.ts ": providers: [HTTP_INTERCEPTOR_PROVIDERS]

    就这些。现在,如果发生任何错误,您可以在拦截器中处理它。

    我的请求代码块没有任何err函数。

    由此:

     this.httpClient.post('http://localhost:8080/api/auth/login', loginModel, httpOptions)
          .subscribe(
            result => {
              this.createToken(result);
            },
            (error) => {
              this.parseError(error);
            }
          );
    

    对此:

     this.httpClient.post('http://localhost:8080/api/auth/login', loginModel, httpOptions)
          .subscribe(
            result => {
              this.createToken(result);
            }
          );
    

    没有更多的错误函数,那是我想要的。