2017-08-04 10 views
2

私はすべてのサービスに対して呼び出されるhttpグローバルサービスを持っています。だから私は最高の例で管理することができます。エラー、アラート、変数など。角度4.3前httpグローバルサービス角度4.3、handleError、401、0などのハンドリングエラー、インターセプター、jwt、ヘッダー

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

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

} 

顧客-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')); 
    } 
} 

私は私が持っている可能性があり、観測していましたエラーをキャッチし、コンポーネント内のグローバルサービス(子サービス内)にオブザーバブルをスローします。今では働いていないと私はキャッチを管理し、新しい角度ガイドで観測

でエラーを処理するかどうかはわかりません:、 https://angular.io/guide/http#error-handling

だけの簡単な方法でエラーを管理

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

今これを適切に管理する方法は何ですか?

答えて

1

私が最終的に解決策を見つけた、エラーがオブジェクトであり、したがって、角度4.3の前に、エラーオブジェクトはResponseで、現在はHttpErrorResponseです。とにかくオブジェクトを取得するので、プロパティを要求することができます。ほとんどの関数は、エラー状態0、サーバーが動作していないときは何も、または角度4.3のインターセプターまたはエラー管理で行ったことが正しい状態を生成しないときは何も考慮しません。

私が見つけた最終的な解決策は、エラーオブジェクトからオブジェクトプロパティを要求するだけです。既知のエラーに対してバックエンドエラーを表示したくない場合はメッセージエラーを定義できます。

環境を探します。TSファイル(角-cliのこのファイルを作成):

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

、グローバルサービスのエラーを処理するには、ことができます:

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が動作します。

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 .... 

    } 
}); 
1

export interface Error{ 
    code:number; 
    error:string[]; 
    errorType:ErrorType; 
} 

export enum ErrorType{ 
    FATAL_ERROR, 
    SYSTEM_ERROR 
} 

あなたははまだ観測を持っていてください、以下のように変更することで対処する

private handleError(error) { 
    if(typeof error === Response){ 
     return Observable.throw(err); 
    } else if(typeof error === Error){ 
     if(error && error.errorMessages && errorMessages.length){ 
      error.errorMessages.forEach(msg=> console.log(error.error)); 
     } 
    } 
} 
4

handleError一般的な方法を使用して、以下のようなエラーシナリオのための厳密な型を定義します。基本的に既存のコンポーネントコードをそのまま残すことができます。変更する必要があるのは、新しいHttpClientを使用するサービスコードだけです。ここで

が私の新しいサービスです。

import { Injectable } from '@angular/core'; 
import { HttpClient, HttpErrorResponse } from '@angular/common/http'; 
import { Observable } from 'rxjs/Observable'; 
import 'rxjs/add/observable/throw'; 
import 'rxjs/add/operator/catch'; 
import 'rxjs/add/operator/do'; 
import 'rxjs/add/operator/map'; 

import { IProduct } from './product'; 

@Injectable() 
export class ProductService { 
    private _productUrl = './api/products/products.json'; 

    constructor(private _http: HttpClient) { } 

    getProducts(): Observable<IProduct[]> { 
     return this._http.get<IProduct[]>(this._productUrl) 
      .do(data => console.log('All: ' + JSON.stringify(data))) 
      .catch(this.handleError); 
    } 

    private handleError(err: HttpErrorResponse) { 
     // in a real world app, we may send the server to some remote logging infrastructure 
     // instead of just logging it to the console 
     let errorMessage = ''; 
     if (err.error instanceof Error) { 
      // A client-side or network error occurred. Handle it accordingly. 
      errorMessage = `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, 
      errorMessage = `Server returned code: ${err.status}, error message is: ${err.message}`; 
     } 
     console.error(errorMessage); 
     return Observable.throw(errorMessage); 
    } 
} 

そして、ここでは基本的には変わらなかった私のコンポーネントのメソッド、次のとおりです。

ngOnInit(): void { 
    this._productService.getProducts() 
      .subscribe(products => this.products = products, 
       error => this.errorMessage = <any>error); 
} 
関連する問題