Purpose: Implementing a global error handler for server errors and application errors generated in Typescript code.
Approach: Utilizing a custom ErrorHandler from a library project within the same workspace. The library structure is as follows:
https://i.sstatic.net/xAaKF.png
Below is the HTTP interceptor (http-error.interceptor.ts)
@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {
constructor(@Inject(LOGGER_SERVICE) private logger: ILoggerService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req)
.pipe(
catchError( (error: HttpErrorResponse) => {
console.log('error');
return throwError(error);
})
);
}
}
Here's the custom global error handler (errors-handler.ts):
import { ErrorHandler, Injectable } from '@angular/core';
@Injectable()
export class ErrorsHandler implements ErrorHandler {
handleError(error: any): void {
console.log('hi!');
}
}
Additionally, the error-handling.module.ts:
import { NgModule, ErrorHandler } from '@angular/core';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { HttpErrorInterceptor } from './http-error.interceptor';
import { ErrorsHandler } from './errors-handler';
@NgModule({
declarations: [],
imports: [
],
exports: [],
providers: [
{provide: ErrorHandler, useClass: ErrorsHandler},
{provide: HTTP_INTERCEPTORS, useClass: HttpErrorInterceptor, multi: true}
]
})
export class ErrorHandlingModule { }
The public_api.ts file solely exports the module
/*
* Public API Surface of error-handling
*/
export * from './lib/error-handling.module';
In the same workspace, an app (Angular CLI's default app, located outside the projects folder) is present. The ErrorHandlingModule is imported in app.module.ts:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { ErrorHandlingModule } from '@common/error-handling';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { CoreModule } from './core/core.module';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule,
CoreModule,
ErrorHandlingModule
],
bootstrap: [AppComponent]
})
export class AppModule { }
The @common/error-handling library has been successfully built. A fake API using json-server defines a "categories" endpoint. This service is called in app.component.ts within the onInit method, resulting in a 404 HTTP error response due to calling the "categorie" endpoint (without "s"). The console output upon serving the app includes:
https://i.sstatic.net/n0VyD.png
While the 404 error and "error" log from http-error.interceptor.ts are visible, the "hi!" log from the custom ErrorHandler is not. The global error handler functions correctly when an error is thrown from app.component.ts after calling the fake API endpoint. However, the line
return throwError(error);
in http-error.interceptor.ts does not reach the global error handler.
Could this issue be related to zone.js? The error seems to be caught there and not propagated to the rest of the application. My understanding of zone.js is limited.
Any other insights?
Thank you in advance!
Regards, Max.