Reputation: 1166
I've implemented HttpInterceptor for catching request errors in my Angular 5 application. My goal is to send another REST POST request to the server, which saves error log. It looks like this:
@Injectable()
export class RestErrorHandler implements HttpInterceptor {
private readonly ERROR_LOGGER_PATH: string = '/logger/errorEntry';
constructor(private http: HttpClient, private restUtils: RestApiUtilsService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).catch((errorReponse: HttpErrorResponse) => {
return this.handleRestError(errorReponse, req, next);
});
}
public handleRestError(error: HttpErrorResponse, req: HttpRequest<any>, next: HttpHandler): ErrorObservable {
let errorMessage = this.prepareErrorMessage(error);
let entry = this.prepareEntry(errorMessage);
this.http.post(this.restUtils.getUrl(this.ERROR_LOGGER_PATH), JSON.stringify(entry), this.restUtils.jsonResponseRequestOptions()).subscribe();
return Observable.throw(error);
}
}
export const ErrorInterceptorProvider = {
provide: HTTP_INTERCEPTORS,
useClass: RestErrorHandler,
multi: true,
};
Later on, I register ErrorInterceptorProvider as a provider in module.
During start of the application, error occurs:
Cannot instantiate cyclic dependency! HttpClient ("[ERROR ->]"): in NgModule AppModule in ./AppModule@-1:-1
Cannot instantiate cyclic dependency! HttpClient ("[ERROR ->]"): in NgModule AppModule in ./AppModule@-1:-1
at NgModuleProviderAnalyzer.parse (compiler.js:19542)
at NgModuleCompiler.compile (compiler.js:20131)
at JitCompiler._compileModule (compiler.js:34430)
at eval (compiler.js:34361)
at Object.then (compiler.js:474)
at JitCompiler._compileModuleAndComponents (compiler.js:34359)
at JitCompiler.compileModuleAsync (compiler.js:34253)
at CompilerImpl.compileModuleAsync (platform-browser-dynamic.js:239)
at PlatformRef.bootstrapModule (core.js:5561)
at eval (main.ts:10)
If I create another @Injectable() service calling rest API through HttpClient, which I inject inside RestErrorHandler there is no error. Why is it?
Upvotes: 0
Views: 485
Reputation: 1166
Here is my final working solution:
@Injectable()
export class RestErrorHandler implements HttpInterceptor {
private readonly ERROR_LOGGER_PATH: string = '/logger/errorEntry';
constructor(private injector: Injector, private restUtils: RestApiUtilsService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).catch((errorReponse: HttpErrorResponse) => {
return this.handleRestError(errorReponse, req, next);
});
}
public handleRestError(error: HttpErrorResponse, req: HttpRequest<any>, next: HttpHandler): ErrorObservable {
let errorMessage = this.prepareErrorMessage(error);
let entry = this.prepareEntry(errorMessage);
if (!this.http) this.http = this.injector.get(HttpClient);
this.http.post(this.restUtils.getUrl(this.ERROR_LOGGER_PATH), JSON.stringify(entry), this.restUtils.jsonResponseRequestOptions()).subscribe();
return Observable.throw(error);
}
}
Upvotes: 0
Reputation: 691635
Just wait for the next angular release, or apply the workaround described in the commit fixing this issue:
Currently this is only possible by injecting the Injector and using it to resolve HttpClient at request time.
Upvotes: 1