401およびその他のエラーをインターセプトして、それに応じて対応したいと思います。これは私のインターセプターです:
import { LoggingService } from './../logging/logging.service';
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent, HttpResponse, HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';
@Injectable()
export class TwsHttpInterceptor implements HttpInterceptor {
constructor(private logger: LoggingService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.logger.logDebug(request);
return next.handle(request)
.do(event => {
if (event instanceof HttpResponse) {
this.logger.logDebug(event);
}
});
}
}
これは200のリクエストに対してうまく機能しますが、エラーの応答をインターセプトしません
Chromeの開発コンソールに表示されるのはこれだけです。
zone.js:2616 GET http:// localhost:8080/backend/rest/wrongurl 404(見つかりません)
またはこれ
zone.js:2616 GET http:// localhost:8080/backend/rest/url 401(無許可)
インターセプターにこれを対処してほしい。私は何が欠けていますか?
Http
はobservableのエラーストリームにエラーを送信するため、.catch
でエラーをキャッチする必要があります(詳細については、こちらを参照してください here )。
return next.handle(request)
.do(event => {
if (event instanceof HttpResponse) {
this.logger.logDebug(event);
}
})
.catch(err => {
console.log('Caught error', err);
return Observable.throw(err);
});
これはおそらく使用するには遅すぎるかもしれませんが、他の誰かがそれを役に立つことを願っています...これは、上記のreturnステートメントを書き直してエラー応答を記録する方法です:
return next.handle(request).do((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
this.logger.logDebug(event);
}
}, (error: any) => {
if (error instanceof HttpErrorResponse) {
this.logger.logDebug(error);
}
});
この同じ方法を使用して、すべての401 Unauthorized応答をログアウトメソッドに直接自動的に送信します(httpの個々の呼び出しで401をチェックするのではなく)。
return next.handle(request).do((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
// process successful responses here
}
}, (error: any) => {
if (error instanceof HttpErrorResponse) {
if (error.status === 401) {
authService.logout();
}
}
});
それは絶対的な魅力のように機能します。 :)
当時私はAngular7 +を試していました。
残念ながら上記のソリューションは、
.do
は、RxJs 6パイプの概念のようにHttpHandler
で直接利用できません。変換Observable to Promise
は固執しません。
これは、クリーンで最新のアプローチです。 pipe
演算子catchError
を使用してエラーを分析し、最後にthrowError
を使用して再スローします。これがインターセプターの最終形状です。
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).pipe(
catchError((error: HttpErrorResponse) => {
if (error.error instanceof ErrorEvent) {
// client-side error or network error
} else {
// TODO: Clean up following by introducing method
if (error.status === 498) {
// TODO: Destroy local session; redirect to /login
}
if (error.status === 401) {
// TODO: Permission denied; show toast
}
}
return throwError(error);
})
);
}
このソリューションが将来誰かを助けることを願っています。
angular 6でHttp応答エラーをインターセプトするには、ObservableをPromiseに変換する少しのトリックを作成します。
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const obs = next.handle(req);
if (!window.navigator.onLine) {
// Handle offline error
this.messageService.showError('No Internet Connection');
return;
}
obs.toPromise().catch((error) => {
this.messageService.progress(false);
this.messageService.showError(error.message);
});
return obs;
}