Hi i am using angular 5 and i am writing a global handler for the same which looks like following.
@Injectable()
export class ErrorsHandler implements ErrorHandler {
constructor(
private injector: Injector,
) { }
handleError(error: Error | HttpErrorResponse) {
const router = this.injector.get(Router);
const zone = this.injector.get(NgZone);
console.log('Here')
console.log(error)
if (error instanceof HttpErrorResponse) {
// Client Error Happend
zone.run(() => router.navigate(['/error'], { queryParams: { error: JSON.stringify(error) } }))
} else {
// Log the error anyway
router.navigate(['/error'], { queryParams: { error: JSON.stringify({ message: 'Failed' }) } });
}
}
}
Everything works fine in Observable world ie if i do a failed http call like following
fireServerError() {
this.httpService
.get('https://jsonplaceholder.typicode.com/1')
.subscribe(data => console.log('Data: ', data));
}
and if the server call fails i get an error object properly as shown in the console image
But instead of that if i change it to a promise using toPromise(), like following
fireServerError() {
this.httpService
.get('https://jsonplaceholder.typicode.com/1')
.toPromise();
}
i get the following string stack trace instead of error Object itself
What am i doing wrong. How to throw/get the error object in case of unhandled promise rejections. Please help. I am stuck;
Please find the stackblitz link Here
1 Answer. Show activity on this post. Once you use . toPromise() , you are essentially putting the behavior into a different execution context (read ECMAScript 10.4), which means that errors must be handled in/around the new execution context rather than having them bubble up in Angular like you are expecting.
Angular CatchError is an RxJs Operator. We can use it to handle the errors thrown by the Angular Observable. Like all other RxJs operators, the CatchError also takes an observable as input and returns an observable (or throws an error).
We use the CatchError to handle the errors thrown by the Angular Observable. Once we handle the error, we must return an observable. We can either return a replacement observable or return an error. The observable returned from CatchError is immediately subscribed.
Always put the “catchError” operator inside a switchMap (or similar) so that it only ends the API call stream and then returns the stream to the switchMap, which continues the Observable.
Once you use .toPromise()
, you are essentially putting the behavior into a different execution context (read ECMAScript 10.4), which means that errors must be handled in/around the new execution context rather than having them bubble up in Angular like you are expecting.
I can't say I entirely follow your example code (is fireServerError
always supposed to throw an error via an HTTP call?), but it seems like you want to try to execute promises without local error handling, but rather to have any error from a promise bubble up to the angular error handling. I'm not sure I'd recommend that, I believe it's best-practice to handle promise errors locally (i.e. using Promise.prototype.catch
or a try/await/catch block
when you create the promise).
That being said, error handling is of course a complicated topic and if you are dead set on just handling all errors at the global level then you can try using a global window event handler to catch all unhandled promise rejections and handle them there:
window.addEventListener("unhandledrejection", event => {
event.preventDefault(); // prevent the default promise rejection behavior
console.error(event); // do whatever you want with the error
}, false);
The MDN guide on promises may also help clear some things up, hope that helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With