Angular 4, custom ErrorHandler does not recognize custom error
I tried to create a custom global ErrorHandler and follow the instructions here
application-error-handler (important parts only)
@Injectable()
export class ApplicationErrorHandler extends ErrorHandler {
constructor(private injector: Injector) {
super(false);
}
handleError(error: any): void {
if (error instanceof ApplicationError || error.originalError instanceof ApplicationError) {
this.addError(error.originalError);
}
else {
super.handleError(error);
}
}
module application
providers: [
{
provide: ErrorHandler,
useClass: ApplicationErrorHandler
}
],
app.component (important part only)
public ngOnInit(): void {
const error = new ApplicationError();
error.message = "fehler";
throw error;
}
application error
export class ApplicationError implements Error {
name: string;
message: string;
httpStatus?: number = 404;
applicationStatus?: number;
errorMessageTranslationkey: string;
handled: boolean = false;
}
in my app.component i throw ApplicationError (in ngOnInit), my ErrorHandler gets called successfully. But my error handleError
always has a type Error
, but error.originalError
always undefined
, regardless of whether I chose my own error and there if
will never be true.
I have no idea why or how this is happening. I can see that the error is getting, so I am assuming it is completed because when I debug I seeerror: Error: [object: Object] at viewWrappedDebugError (vendor.bundle.js)
Any idea what might be causing this problem and how I can solve it?
EDIT
As expected, this is Debugmode related. As soon as I activate prodmode with enableProdMode();
it works as expected.
However, this does not answer my question yet.
How can I handle my own error in angular debug mode?
source to share
You are having this problem because it is ApplicationError
not Error
.
You can use the following code to create a custom error:
export class ApplicationError extends Error {
httpStatus?: number = 404;
applicationStatus?: number;
errorMessageTranslationkey: string;
handled: boolean = false;
constructor(message?: string) {
super(message);
this.name = ApplicationError.name;
Object.setPrototypeOf(this, ApplicationError.prototype);
}
}
In connection with the topic of creating a custom error, check out these links as well for a complete understanding of the matter:
Why should it be an Error instance? As your error goes through the following method:
function viewWrappedDebugError(err, context) {
if (!(err instanceof Error)) {
// errors that are not Error instances don't have a stack,
// so it is ok to wrap them into a new Error object...
err = new Error(err.toString());
}
_addDebugContext(err, context);
return err;
}
The code is available in errors.ts
.
So if you don't throw away the instance Error
, a new instance is created.
Intercepting uncovered promises in ErrorHandler
Another case of error is when you return a promise that is rejected from your method that is called by the Angular lifecycle (ex: handler, lifecycle binding).
export class AppComponent implements OnInit {
ngOnInit() {
return new Promise((resolve, reject) => reject(new ApplicationError()));
}
}
Therefore, the error handling code might look like this:
import {ErrorHandler, Injectable, Injector} from "@angular/core";
import {ApplicationError} from "./ApplicationError";
@Injectable()
export class ApplicationErrorHandler extends ErrorHandler {
private errors: ApplicationError[] = [];
constructor(private injector: Injector) {
super(false);
}
handleError(error: any): void {
if (error instanceof ApplicationError) {
this.addError(error);
}
else {
if(error.rejection instanceof ApplicationError) {
this.addError(error.rejection);
}
else {
super.handleError(error);
}
}
}
addError(error: ApplicationError) {
this.errors.push(error);
}
}
source to share