Angular2 ExceptionHandler - check if error object

2019-09-14 01:45发布

问题:

I am currently using the following code to handle exceptions:

@Injectable()
export class CustomExceptionHandler extends ExceptionHandler {
call(error, stackTrace = null, reason = null) {
    console.warn(error);
}

The code works fine, I can see the error in the console. The error is a Response object, defined in @angular/core. However, the error parameter is 'any'. I can't change the error type (e.g. error:Response), because it wont necessarily be a Response object, it could be anything.

I wanted to use (error instanceof Response), but that wont work, because error is a type of object, which makes sense.

UPDATE

So it turns out (error instanceof Response) does work after all. For some reason it doesn't appear to work when you're debugging the typescript using VS Code. I put a watch on it and it always returned false. Maybe it's because i'm not checking at run-time

Anyway, important thing is that in the context of Angular2 Response objects, instanceof will work just fine as they do have a constructor

Thank to @DanSimon for helping to narrow down what was going wrong, and for providing other ways to check the type of an object!

回答1:

Interesting question. Since TypeScript is really just compiling down to JS, classes don't really exist. I can think of two ways you could check, you can use a "User-Defined Type Guard" or use the "instanceof type guard". The User-Defined Type Guard is just a fancy way of checking a property/function of the object to determine its Type, the advantage is TS won't complain about a "missing property/function". Using the "instanceof" works but only if the Object has a constructor as it's comparing the two Object's constructors. So if your Object doesn't have a constructor it's a no go. You can find the documentation for these two here.

I also made a plunker demonstrating how they work. The results will load into the console, so use your browsers debug tool to see the results. All the work is being done on "app/child.component.ts" in the "ngOnChanges" function.

ngOnChanges(changes: {[propertyName: string]: SimpleChange}) {
  console.log();
  console.log("Custom function isSimpleChange:", this.isSimpleChange(changes));
  console.log("Using instanceof SimpleChange:", (changes instanceof SimpleChange));
  console.log("Using Object.prototype.toString.call():", Object.prototype.toString.call(changes));
  console.log("Logging the object itself:",changes);
  console.log("-----------------------------------------------------------------------------------------");
  let testExample = new ExampleObject();
  console.log("Custom function isExampleObject:", this.isExampleObject(testExample));
  console.log("Using instanceof ExampleObject:", (testExample instanceof ExampleObject));
  console.log("Using Object.prototype.toString.call():" + Object.prototype.toString.call(testExample));
  console.log(testExample);


  this._result = changes.value.currentValue;
  this._changes++;
}

You will probably need to leverage both and also "typeof" for your primitive types to do a complete inspection of the object. So using "typeof" to check for basic types "string","number","boolean". Then using "instanceof" to see if the constructors match, finally using a "User-Defined Type Guard" to look for specific "properties/functions".