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!