Sebastian S
Sebastian S

Reputation: 397

Angular handleError: How to get custom API error messages?

I'm trying to solve another Angular problem - can you help me? In my component I have a login function - like this:

    onLogin() {
    if (this.loginForm.valid) {
      const email = this.loginForm.get(['email']).value;
      const password = this.loginForm.get(['password']).value;

      this.ls.login(email, password).subscribe(
        result => {
          this.saveToken(result);
        },
        error => {
          this.errorMessage = error;
          this.loginForm.reset();
        }
    );

    } else {
      this.updateErrorMessage();
    }
  }

My service function looks like that:

login(email: string, password: string): Observable<string> {

    const apiUrl = environment.apiHostLumen + '/admin/login?email=' + email + '&password=' + password;

    const headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
    const options = new RequestOptions({ headers: headers });

    return this.http.get(apiUrl, options).pipe(
                    retry(3),
                    map(res => res.json()),
                    map(data => {
                      return data.token;
                    }),
                    catchError(this.ehs.handleError('login'))
    );

  }

Now I have implemented the function for error handling exactly as described in the documentation of Angular. I have outsourced the feature and it looks like that:

handleError<T> (operation = 'operation', result?: T) {
    return (error: HttpErrorResponse): Observable<T> => {

      const userMessage = error.message;

      return throwError(userMessage);
    };
  }

But how it's possible to access the body of the API response? error.message is always undefined. I only have access to the status code and url. How can I access the response body if the API returns an error code different from 200 ?

Thanks a lot

Upvotes: 1

Views: 5537

Answers (3)

Anuradha Gunasekara
Anuradha Gunasekara

Reputation: 6983

You can use a HttpInterceptor for this. From that you can handle all your http errors in a single class. You can read more about Intercepting requests and responses in the angular official doumetation.

And by using intercept method you can intercept each and every request and response.

 public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next
      .handle(req)
      .pipe(catchError(err => {
        if (err instanceof HttpErrorResponse) {
          this.onError(err);
        }
        return throwError(err);
      }));
  }



 private onError(response: HttpErrorResponse): void {
    const status: number = response.status;
    const serverErrorMessage = response.error;

    switch(status) {
      case 400:
        console.log("Bad request"); //or you can print the serverErrorMessage
      case 404:
        console.log("Not found");
    }
  }

Upvotes: 3

Sebastian S
Sebastian S

Reputation: 397

I have found the mistake. Many thanks for your help! I renamed the error type to any and with error.json() I can actually access the response body as normal. I do not know how I could overlook that ...

Thanks! It seems to work!

Upvotes: 1

Amit Chigadani
Amit Chigadani

Reputation: 29705

You can do error.error, which should give you the error response from the server.

handleError<T> (operation = 'operation', result?: T) {
    return (error: HttpErrorResponse): Observable<T> => {

      const userMessage = error.error; // should give error body

      return throwError(userMessage);
    };
}

Sources :

https://angular.io/api/common/http/HttpErrorResponse

Accessing HTTP Error Response Body from HttpInterceptor in Angular

Upvotes: 1

Related Questions