HttpErrorResponseを処理するcatchブロックを持つグローバルHttpInterceptorがあります。しかし、私の要件は、サービスがhttp呼び出しを行い、エラーハンドラーもある場合、サービスのエラーハンドラーを最初にオフにすることです。このサービスにエラーハンドラーがない場合は、グローバルHttpInterceptorエラーハンドラーで処理する必要があります。
コード例:
HTTPインターセプター:
@Injectable()
export class ErrorHttpInterceptor implements HttpInterceptor {
constructor(private notificationService: NotificationService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req)
.catch(
error => {
if (error instanceof HttpErrorResponse) {
this.notificationService.error('Error', 'Error in handling Http request');
}
return Observable.empty<HttpEvent<any>>();
}
);
}
}
そしてサービスコール:
updateUser(id, data) {
return this.http
.patch(`${API.userUrl}/${id}`, {data: data})
.subscribe(
() => console.log('success'),
(err) => this.notificationService.error('custom code to handle this')
);
}
この場合、ErrorHttpInterceptorが通知を送信し、次にuserServiceエラー処理もエラー通知を送信します。
しかし、私のユースケースでは、基になるサブスクリプションがエラーを処理しなかった場合にのみ、ErrorHttpIntercetorでエラーを処理します。これを行う方法はありますか?
解決する1つの方法は、リクエストでhttpHeaders
を渡すことです。
request() {
const url = 'GoalTree/GetById/';
let headers = new HttpHeaders();
headers = headers.append('handleError', 'onService');
this.http.get(url, {headers: headers})
.pipe(
map((data: any) => {
this.showError = false;
}),
catchError(this.handleError)
)
.subscribe(data => {
console.log('data', data);
})
}
Interceptor.ts:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.spinnerService.show();
return next.handle(req).do(
(event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
this.spinnerService.hide();
}
},
(err: any) => {
if (req.headers.get('handleError') === 'onService') {
console.log('Interceptor does nothing...');
} else {
console.log('onInterceptor handle ', err);
}
}
);
}
リクエストヘッダーのin interceptor
のエラーコールバックを確認してください。ただし、このソリューションでは、Interceptorsがサービスを呼び出す前にリクエストを処理します。
これは私がこれまでに思いついた最良の解決策です。
インターセプターで、エラーオブジェクトに新しいサブスクリプションプロパティを作成し、エラーを再スローします。
return next.handle(authReq).pipe(
catchError((err: any, caught: Observable<HttpEvent<any>>) => {
err.defaultHandler = timer(0).subscribe(() => {
this.notify.error('Server Error', 'Server Error Message');
});
return throwError(err);
})
);
実際にエラーを処理したい場合は、上記で作成したタイマーサブスクリプションの登録を解除します。
this.authService.login(authRequest).subscribe((x) => {
this.navigateDefaultRoute();
}, (err) => {
// Prevent default error from being handled
err.defaultHandler.unsubscribe();
this.notify.error('Invalid Credentials', 'Email and password did not match');
});