8

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

Gelu
  • 955
  • 2
  • 11
  • 21
  • try to print whole error object in console and check status and message are there or not. some times it is `error.error.status` and `error.error.message`. – ashish pal Jan 31 '19 at 15:44
  • Ashish, I'm already printing the error object (first line in handleError). It contains... nothing (check the picture in the updated question). – Gelu Jan 31 '19 at 15:49
  • can you set a breakpoint in your error handler method and check the value of the `error` argument? My guess is that the object passed isnt trully a `HttpErrorResponse` instance – Jota.Toledo Jan 31 '19 at 15:56
  • try console.log once – ashish pal Jan 31 '19 at 15:56
  • Jota and Ashish, no luck. Check the updated question, that object is empty :_( – Gelu Jan 31 '19 at 16:06

3 Answers3

18

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.

Gelu
  • 955
  • 2
  • 11
  • 21
2

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:

Michael Karén
  • 1,105
  • 9
  • 13
  • Thanks Michael. I tried returning Content() but no luck. I have a centralized error handler + some specific error handlers for some scenarios. But I still have the same issue. I can recognize an error, but not the specific kind of error (status code, message...). I'll take a look at the article. – Gelu Feb 08 '19 at 12:24
  • I found something in our solution that you can try out. I will update the answer. – Michael Karén Feb 08 '19 at 13:30
0

In the response the property is called "Message" and not "message".

  • I don't think that the error.message and the Message property of the json response are the same. Right? Otherwhise what if the json object doesn't have that propery? – Gelu Jan 31 '19 at 15:34
  • What do you see when you "open" the warn-log in the console? – Gundelino85 Jan 31 '19 at 15:36
  • It is just the callstack generated by chrome (check the pic in the updated question). – Gelu Jan 31 '19 at 15:47