If you want to intercept errors when using HttpClient
service to make backend calls and don't repeat yourself in every call you make, you need to use interceptor.
This is what we use in our application and depending on the type of error: 500, 400, 404, 403, we redirect, show payment modal or just show toast message:
Http status error codes:
export class HttpError{
static BadRequest = 400;
static Unauthorized = 401;
static Forbidden = 403;
static NotFound = 404;
static TimeOut = 408;
static Conflict = 409;
static InternalServerError = 500;
}
Interceptor code:
import {Injectable, Injector} from '@angular/core';
import {HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http'
import {Observable} from 'rxjs/Observable';
import {AuthorizationService} from "../authorization.service/authorization.service";
import {HttpError} from "./http-error";
import {Router} from "@angular/router";
import {Toaster} from "nw-style-guide/toasts";
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
// Regular dep. injection doesn't work in HttpInterceptor due to a framework issue (as of [email protected]),
// use Injector directly (don't forget to add @Injectable() decorator to class).
constructor(private _injector: Injector) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const logFormat = 'background: maroon; color: white';
return next.handle(req)
.do(event => {
}, exception => {
if (exception instanceof HttpErrorResponse) {
switch (exception.status) {
case HttpError.BadRequest:
console.error('%c Bad Request 400', logFormat);
break;
case HttpError.Unauthorized:
console.error('%c Unauthorized 401', logFormat);
window.location.href = '/login' + window.location.hash;
break;
case HttpError.NotFound:
//show error toast message
console.error('%c Not Found 404', logFormat);
const _toaster = this._injector.get(Toaster),
_router = this._injector.get(Router);
_toaster.show({
message: exception.error && exception.error.message ? exception.error.message :
exception.statusText,
typeId: 'error',
isDismissable: true
});
_router.navigate(['']);
break;
case HttpError.TimeOut:
// Handled in AnalyticsExceptionHandler
console.error('%c TimeOut 408', logFormat);
break;
case HttpError.Forbidden:
console.error('%c Forbidden 403', logFormat);
const _authService = this._injector.get(AuthorizationService);
_authService.showForbiddenModal();
break;
case HttpError.InternalServerError:
console.error('%c big bad 500', logFormat);
break;
}
}
});
}
}
You also need to add the interceptor into @NgModule providers where you bootstrap your app:
{
provide: HTTP_INTERCEPTORS,
useClass: ErrorInterceptor,
multi: true
},
Modify the code according to your needs - when started - we were just logging things to the console. Once you have this interceptor in place, it will handle all backend requests that go though HttpClient service.