Angular handle for 500 server errors
Asked Answered
E

4

13

How can I modify my http call to handle(catch) for 500 server errors. I try calling an API but receive a '500 (Internal server error' in the 'err' part of the function. I would like to be able to catch it if possible but am not sure how. Is there a simple way to do this?

  call_http() {
    this.http.get<any>('/api/goes/here').subscribe(data => {
      this.result = data;
    },
      err => {
        console.log(err);
      });
  }

I am not using any headers, map, errorhandler etc. This is just a basic call.

Environ answered 2/10, 2018 at 14:13 Comment(3)
What do you mean by "cater"? It's unclear what you wantYorkist
I have updated wordingEnviron
Possible duplicate of Angular 4 - Observable catch errorGennagennaro
C
24

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.

Cthrine answered 2/10, 2018 at 14:28 Comment(2)
this is should be the correct answer. As this is the correct way of handling these 4xx and 5xx erorsThea
The best answer for unhandled 5xx errors! Thank you!Franklynfrankness
M
10

You can check the http status code in error object and warn the user or do some other action

call_http() {
    this.http.get<any>('/api/goes/here').subscribe(data => {
      this.result = data;
    },
      err => {
        console.log(err);
       // check error status code is 500, if so, do some action
      });
  }
Mauritamauritania answered 2/10, 2018 at 14:27 Comment(0)
A
5
  err => {
    if(err.status==500)
    console.log(err)
  });

}

Arithmetician answered 2/10, 2018 at 14:13 Comment(0)
Y
1
call_http() {
    this.http.get<any>('/api/goes/here').pipe(
      map(res => this.result = res),
      catchError(err => do something with err)
    ).subscribe();
}

The above should allow you to catch the error and do whatever you need.

Yorkist answered 2/10, 2018 at 14:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.