使用 http 全局服务 Angular 4.3、handleError、401、0 等、拦截器、jwt、标头处理错误 [英] handling error with http global service angular 4.3, handleError , 401, 0, etc, interceptor , jwt, headers

查看:13
本文介绍了使用 http 全局服务 Angular 4.3、handleError、401、0 等、拦截器、jwt、标头处理错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 http 全局服务,它被所有服务调用;所以我可以以身作则,做到最好;错误、警报、变量等.

I have a http globalservice that it's called for all services; so i can manage best by example; errors, alerts, variables,etc.

customers.service.ts

customers.service.ts

export class CustomersService {
  childUrl = environment.apiUrl + 'customers';

  constructor(
    private http: HttpClient,
    private globalService: GlobalService
   ) {


  }

  public get(childUrl)  {
    return this.globalService.get(this.childUrl)
      .catch((res: Response) => this.handleError(res));
  }
  ...
  private handleError(err) {
    return Observable.throw(err);
  }
}

global.service.ts

global.service.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse, HttpHeaders  } from '@angular/common/http';
import { environment } from '../../environments/environment';

@Injectable()
export class GlobalService {

  url: string,

  constructor(private http: HttpClient) {

    this.headers = new HttpHeaders()
      .set('Content-Type', 'application/json; charset=utf-8')
      .set('Accept', 'application/json');


  }

  public prepare ( vars ) {
    this.url = environment.apiUrl + vars.childUrl;
  }
  public get( childUrl)  {

    this.prepare ({childUrl} );

    return this.http.get(this.url, { headers: this.headers, observe: 'response'})
      .catch((res: Response) => this.handleError(res);
  }
  private handleError(err) {
    return Observable.throw(err);
  }

}

customers-list.component

customers-list.component

export class CustomersListComponent implements OnInit {

  public customers: Array <any>;

  constructor (private customersService: CustomersService ) { }

  ngOnInit() {
    this.get();
  }

  private get(): void {
    this.customerService
      .get()
      .subscribe((data) => {this.customers = data.data; console.log(data) },
        error => console.log(error),
        () => console.log('Get all Items complete'));
  }
}

在 Angular 4.3 之前,我有 observables ,我可以捕获错误,并在组件中的全局服务、子服务中抛出一个 observable.现在它不工作了,我不确定如何管理 catch,并使用 observables 处理错误

before angular 4.3 I had observables , i could have catch for the error, and throw an observable in global service, in child service, in the component. Now it's not working and i'm not sure how to manage catch, and handle error with observables

在新的角度指南中:https://angular.io/guide/http#error-handling

只需以简单的方式管理错误,

just manage error in a simple way,

http
  .get<ItemsResponse>('/api/items')
  .subscribe(
    data => {...},
    (err: HttpErrorResponse) => {
      if (err.error instanceof Error) {
        // A client-side or network error occurred. Handle it accordingly.
        console.log('An error occurred:', err.error.message);
      } else {
        // The backend returned an unsuccessful response code.
        // The response body may contain clues as to what went wrong,
        console.log(`Backend returned code ${err.status}, body was: ${err.error}`);
      }
    }
  });

现在管理这个的正确方法是什么?

what is the right way to manage now this ?

推荐答案

我终于找到了解决方案,errors是对象,所以在angular 4.3之前error对象是一个Response,现在是HttpErrorResponse,反正我们得到的是对象,所以我们可以要求属性.大多数函数不考虑错误状态 0,当服务器不工作时,或者当您的 Angular 4.3 中的拦截器或您在错误管理中所做的任何事情都没有产生正确的状态时.

I've found finally a solution, errors are objects, so before angular 4.3 the error object was a Response, now its HttpErrorResponse, anyway we get objects, so we can ask for properties. Most of functions don't consider the error status 0, o nothing when the server is not working, or when your interceptor in angular 4.3 or anything you did in your error manage don't produce correct status.

我找到的最终解决方案只是简单地从错误对象中询问对象属性,并且我可以定义消息错误以防我不想显示已知错误的后端错误.

the final solution i've found is just simply ask for object properties from error object, and I can have define messages errors in the case i don't want show backend errors for known errors.

查找 environment.ts 文件(angular-cli 创建此文件):

look for environment.ts file ( angular-cli create this file ):

export const environment = {
  production: false,
  apiUrl: 'http://localhost:3000/',
  httpErrors: {
    0:   { 'msg': 'Server is not available'},
    404: { 'msg': 'Page not Found'},
    401: { 'msg': 'Not Authorized'}
  }
};

那么全局服务的处理错误可以是:

then handle error for the global service can be:

  private handleError(err: any) {
    console.log( 'Error global service');
    console.log(err);
    let errorMessage = '';

    if (err.hasOwnProperty('status') ) { // if error has status
      if (environment.httpErrors.hasOwnProperty(err.status)) {
         errorMessage = environment.httpErrors[err.status].msg; // predefined errors
      } else {
        errorMessage = `Error status: ${err.status}`;
        if (err.hasOwnProperty('message')) {
          errorMessage +=  err.message;
        }
      }
    }
    if (errorMessage === '') {
      if (err.hasOwnProperty('error') && err.error.hasOwnProperty('message') ) { // if error has status
        errorMessage = `Error: ${err.error.message}`;
      }
    }
    if (errorMessage === '')  errorMessage = environment.httpErrors[0].msg; +// no errors, then is connection error
   this.snackBar.open(errorMessage, 'Close', {
      duration: 5000
    });
    console.error(errorMessage);
    return Observable.throw(errorMessage);
  }

在你的拦截器中

import {HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpErrorResponse} from '@angular/common/http';
import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/Observable';

@Injectable()
export class InterceptorService implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (localStorage.getItem('SignIn-Token')) {
      req = req.clone({
        setHeaders: {
          authorization: localStorage.getItem('SignIn-Token')
        }
      });
    }
    return next.handle(req).catch(err => {
      if (err instanceof HttpErrorResponse) {
        console.log('interceptor error');
        console.log(err);
        if (err.status === 401) {
          // JWT expired, can be setted to go to login
          return Observable.throw(err);
        } else {
          return Observable.throw(err);
        }
      }
    });
  }
}

如果你使用下面的代码在你的拦截器中出错,handleError 仍然可以工作:

if you make an error in your interceptor by example with the code below, the handleError will work anyway:

return next.handle(req).catch(err => {
  if (err instanceof HttpErrorResponse) {
    console.log('interceptor error');
    console.log(err);
    if (err.status === 401) {
      // JWT expired, can be setted to go to login
      return Observable.throw(err);
    }
    // here you are not return observable so, your global service get nothing of status ....

  }
});

这篇关于使用 http 全局服务 Angular 4.3、handleError、401、0 等、拦截器、jwt、标头处理错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆