Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 6 error handlig - HttpErrorResponse has undefined status

I have a Angular 6 client consuming a REST Api developed with .Net Web Api.

Everything is working except for the error handling. When I try to process the error to react differently to different status codes (404, 403, 409, 500...) I simply can't make it work. The HttpErrorResponse object doesn't have any of the fields it is supposed to (like 'status' or 'error').

I've made a super simple service that reproduces the issue:

Request on the service.ts

 public test(): Observable<any> {
    let url = this.templatesUrl + '/myMethod';
    console.log('GET myMethod ' + url);

    return this.http.get<any>(url)
                      .pipe(catchError(this.handleError));
  }

Error handler (pretty much straight from the official documentation):

 private handleError(error: HttpErrorResponse) {
    console.warn(error);

    if (error.error instanceof ErrorEvent) {
      // A client-side or network error occurred. Handle it accordingly.
      console.error('An error occurred:', error.error.message);
    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong,
      console.error(
        `Backend returned code ${error.status}, ` +
        `body was: ${error.message}`);
    }
    // return an observable with a user-facing error message
    return throwError('Unexpected error');
  }

Service on the .Net side:

[HttpGet]
[Route("myMethod")]
public IHttpActionResult myDotNetMethod()
{
    return InternalServerError(new Exception("Details about the issue"));
}

The service is called and it returns a status code 500 along with a json object:

The status of the response:

Chrome showing the request

The response header, it is json:

Response header, it is json

The json object:

The json object returned

And what the log shows: no status and pretty much an empty object:

What the log shows, no status and pretty much an empty object

Loosk like the HttpErrorResponse is pretty much empty. But the response from the API was fine, the status code is there and the json object too.

What am I missing?

Update: In case you are wonder what hides behind that "Internal Server Error" that shows in the log (it is just the callstack generated by chrome):

enter image description here

Update 2: Here's the error object under the microscope. It is simply "Internal Server Error". No trace of status or message.

enter image description here

like image 271
Gelu Avatar asked Jan 31 '19 15:01

Gelu


People also ask

What is httpErrorResponse in Angular?

HttpErrorResponselink A response that represents an error or failure, either from a non-successful HTTP status, an error while executing the request, or some other failure which occurred during the parsing of the response.

How handle error in Angular 6?

One traditional way of handling errors in Angular is to provide an ErrorHandler class. This class can be extended to create your own global error handler. This is also a useful way to handle all errors that occur, but is mostly useful for tracking error logs.

How do you get httpErrorResponse?

Whenever the error occurs in an HTTP operation, the Angular wraps it in an httpErrorResponse Object before throwing it back. We catch the httpErrorResponse either in our component class or in the data service class or globally. The Global HTTP error handling is done using the Angular HTTP Interceptor.


2 Answers

Solved... the object was empty due to an interceptor. So if something similar is happening to you check those out.

I'm sorry to have wasted everyone's time, I was unaware of the existance of that particular interceptor.

like image 127
Gelu Avatar answered Sep 29 '22 00:09

Gelu


I think your problem is how you are throwing the error in .Net. Try this:

var statusCode = HttpStatusCode.InternalServerError;

var response = new HttpResponseMessage(statusCode)
{
    Content = new ObjectContent<object>(
        new
        {
            Message = "Error Message",
            ExceptionMessage = "StackTrace"
        },
        new JsonMediaTypeFormatter())
};

throw new HttpResponseException(response);

Or if it does not work try this: https://stackoverflow.com/a/28589333/8758483

Another good idea is to centralize your error handling by implementing an ErrorHandler in Angular.

import { ErrorHandler } from '@angular/core';

@Injectable()
export class GlobalErrorHandler implements ErrorHandler {  
  handleError(error) {
    // your custom error handling logic    
  }
}

Then you tell Angular you want to use this class instead of the default one by providing it in you NgModule:

@NgModule({   
  providers: [{provide: ErrorHandler, useClass: GlobalErrorHandler}]
})

If you want more detail you can read this article:

  • Expecting the Unexpected — Best practices for Error handling in Angular
like image 41
Michael Karén Avatar answered Sep 28 '22 22:09

Michael Karén