简体   繁体   English

观测值的Angular HttpClient默认错误函数

[英]Angular HttpClient Default Error Function For Observables

At backend I have created a nice Exception mechanism so when a request fail. 在后端,我创建了一个很好的Exception机制,因此当请求失败时。 Server going to send a nice error message to client with some error code . 服务器将发送一些错误代码给客户端一个不错的错误消息。

Like this: 像这样:

@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;
...
}

I want to show error messages to user by default for each fail. 对于每个失败,我想默认向用户显示错误消息。

I have tried to extend HttpClient 我试图扩展HttpClient

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

But it's returning an Observable 但是它返回了一个Observable

In most of page I am doing something like this.: 在大部分页面中,我正在执行以下操作:

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

In a lot of pages I am writing the same thing : 在很多页面中,我都在写同样的东西:

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

I read this post which about extending HttpClient. 我读了这篇有关扩展HttpClient的文章。
But it is not enough for me it's only defining a default "API_HOST" I want to define default error function for request methods return objects and they are Observables. 但这对我来说还不够,仅定义一个default "API_HOST"我想为请求方法返回对象定义默认错误函数,它们是可观察的。

Is there anyway to manipulate returning object of "HttpClient Request Methods" like extending? 无论如何,有没有像扩展那样操纵“ HttpClient请求方法”的返回对象?

You can use the new HTTPClient interceptors that are made for that. 您可以使用为此专用的新HTTPClient拦截器

Here is an example of one : 这是一个例子:

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);
        }
      );
  }

}

At every HTTP request performed by Angular, this interceptor will be ran, and will behave the way you tell it to do. 在Angular执行的每个HTTP请求中,此拦截器都会运行,并按照您告诉它的方式运行。 In this case, it will log the error, but you can make him do whatever you want. 在这种情况下,它将记录错误,但是您可以让他执行您想要的任何操作。

what I personally do to centralize error handling, is the following: 我个人为集中错误处理所做的工作如下:

In my Service, I intercept the http Requests with catchError like 在我的服务中,我使用catchError拦截了HTTP请求,例如

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

The error handling (in my case, logging dependent of the HTTP return status and the return value) is done in the handleError method like 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);
  }

` `

I also declared a global noop function 我还声明了全局noop函数

export function noop() {}

so that all my service consumers only call 这样我所有的服务使用者都只会打电话

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

Maybe that attempt is also suitable for you? 也许这种尝试也适合您?

Thanks to trichetriche, If you want to make a centralized exception handling with "HttpClient" here is my final code: 感谢trichetriche,如果您想使用“ HttpClient”进行集中式异常处理,这是我的最终代码:

1) Create a interceptor: 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);
        }
      ));
  }

}

Snack is a customized snackbar with that I notify user. 小吃是定制的小吃店 ,我会通知用户。

2) Provide your interceptor: 2)提供您的拦截器:

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

Add this into your project module it can be " app.module.ts ": providers: [HTTP_INTERCEPTOR_PROVIDERS] 将此添加到您的项目模块中,它可以是“ app.module.ts ”: providers: [HTTP_INTERCEPTOR_PROVIDERS]

Thats all. 就这样。 Now if any error occurs you can handle it in your interceptor. 现在,如果发生任何错误,您可以在拦截器中进行处理。

And my request code blocks don't have any err function. 而且我的请求代码块没有任何err函数。

From this: 由此:

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

To this: 对此:

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

No more error function and that was I want. 没有更多的错误功能,那是我想要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM