I'm trying to throw custom errors in my resolvers that I catch with my global error handler. I can throw errors in a component and they come through fine, but when I throw them in the resolver their type is changed to the standard Error
type.
Here is a functioning repro: https://stackblitz.com/edit/angular-gitter-vvgys6
Setup
class DisplayableError extends Error {
// ...
}
@Injectable()
export class GlobalErrorHandlerService {
constructor() { }
handleError(error) {
console.log('GOT ERROR instance of DisplayableError', error instanceof DisplayableError);
}
}
Working usage
in any component I can just throw an error and it's caught in the global error handler and it is an instance of DisplayableError
.
throw new DisplayableError('blah');
Broken usage
When I throw the error in the resolver the instance type is changed to Error
and instanceof DisplayableError
returns false.
@Injectable()
export class StoreGetResolver implements Resolve<StoreModel> {
constructor(
private storeService: StoreService,
) { }
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<StoreModel> {
let storeId = route.paramMap.get('storeId');
return this.storeService.get(storeId)
.catch(error => Observable.throw(new DisplayableError('my custom error')));
}
}
I've also tried this
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<StoreModel> {
let storeId = route.paramMap.get('storeId');
return this.storeService.get(storeId)
.do(
() => { },
error => throw new DisplayableError('my custom error')
);
}
...and even this
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<StoreModel> {
throw new DisplayableError('my custom error');
}
The constructor for DisplayableError is called with the correct data and the message even makes it to the global error handler, but the the error is of type Error
instead of DisplayableError
when it gets there
This is a known issue with Typescript: https://github.com/Microsoft/TypeScript/issues/13965
The workaround is to do some fiddling with the prototype:
// Use this class to correct the prototype chain.
export class MyError extends Error {
__proto__: Error;
constructor(message?: string) {
const trueProto = new.target.prototype;
super(message);
// Alternatively use Object.setPrototypeOf if you have an ES6 environment.
this.__proto__ = trueProto;
}
}
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