2

I'm trying to handle errors returned by my .NET Core WebApi from an Angular 4.3 service using the new HttpClientModule.

I'm making the http request as follows:

postUser(model: IPostUser): Observable<IUser> {
    return this.http.post<IUser>(this.originUrl + '/api/registry', model)
        .catch((reason: any) => this.handleError(reason));
}

the handleError method is:

private handleError(error: HttpErrorResponse | any): ErrorObservable {
    // in a real world app, we might use a remote logging infrastructure
    let errStatus: string;
    let errMsg: string;
    if (error instanceof HttpErrorResponse) {
        try {
            const body: any = error.error || error;
            const err: string = body.message || JSON.stringify(body);
            errStatus = `${error.status} - ${error.statusText || ''}`;
            errMsg = `${err}`;

            if (error.status === 0) {
                errMsg = 'Si é verificato un errore. Si prega di riprovare più tardi.';
            } else if (error.status === HttpStatusCodes.UNAUTHORIZED || error.status === HttpStatusCodes.FORBIDDEN) {
                errMsg = 'Non hai effettuato l\'accesso.';
            }
        } catch (ex) {
            errMsg = 'Si é verificato un errore. Si prega di riprovare più tardi.';
        }
    } else {
        errMsg = error.message ? error.message : error.toString();
    }
    console.error(errStatus + ': ' + errMsg);
    this.toastrService.error(errMsg, 'Errore');
    return Observable.throw(errMsg);
}

And the WebApi controller action makes the following security checks:

var user = await _userManager.FindByIdAsync(model.Id);
if (user == null)
    return NotFound("Utente non trovato.");

if ((await _userManager.FindByNameAsync(model.UserName)) != null)
    return BadRequest("Esite già un utente con questo Username.");
else if ((await _userManager.FindByEmailAsync(model.Email)) != null)
    return BadRequest("Esite già un utente con questa Email.");
else if ((await _userManager.Users.SingleOrDefaultAsync(u => u.TaxCode == model.TaxCode)) != null)
    return BadRequest("Esite già un utente con questo Codice Fiscale.");

So depending on what user try to post to the server, the server throw a NotFound or BadRequest respose with a body that is an object containing a message.

A bad call to that WebApi action cause this error:

undefined: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

I've tried to use an HttpInterceptor to catch the error response body:

@Injectable()
export class ErrorInterceptor implements HttpInterceptor {

constructor(private router: Router) { }

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    return next.handle(req).do((event: HttpEvent<any>) => {
        if (event instanceof HttpResponse) {
            // do stuff with response if you want
        }
    }).catch((error: any) => {
        if (error instanceof HttpErrorResponse) {
            let x = error;
            if (error.status === HttpStatusCodes.BAD_REQUEST || error.status === HttpStatusCodes.NOT_FOUND) {
                return Observable.throw(error);
            }
        }
    })
}

}

But also with the interceptor the error is still the same anche the catch method right after the post call in the Angular service was called with the TypeError exception shown above rather than my custom error object.

Any solution? How can I catch a BadRequest/NotFound error response from the server and get the error response body correctly?

Thank you all in advance!

Maximilian Riegler
  • 22,720
  • 4
  • 62
  • 71
Androidian
  • 1,035
  • 1
  • 16
  • 40

1 Answers1

1

I found the problem. I've another interceptor that returns an Observable.throw(..) only for 401 and 403 error responses. Making it always return the exception solves the problem.

Androidian
  • 1,035
  • 1
  • 16
  • 40