Search code examples
typescriptbluebird

Bluebird's filtered catch broken when JS is generated by Typescript 2.0


The error I see is identical to this (from here:Catch Error Type in Bluebird Not Working):

I have a custom error class:

class NetworkError extends Error {
  constructor() {
    super('Network Error');
    this.name = 'NetworkError';
  }
}

And I want to handle it specifically:

import {NetworkError} from '../../common/errors';
someFunc().catch(NetworkError, err => {
  // this is missed
}).catch(err => {
  // this is hit
});

But it's skipping my custom catch and hitting the general catch. If I change it like so, it works:

someFunc().catch({name: 'NetworkError'}, err => {
  // this is hit
}).catch(err => {
  // this is missed
});

Obviously the first way is preferred. What am I missing here?


Solution

  • The cause is the latest upgrade to Typescript 2.0. Specifically:

    As part of substituting the value of this with the value returned by a super(...) call, subclassing Error, Array, and others may no longer work as expected. This is due to the fact that constructor functions for Error, Array, and the like use ECMAScript 6's new.target to adjust the prototype chain; however, there is no way to ensure a value for new.target when invoking a constructor in ECMAScript 5. Other downlevel compilers generally have the same limitation by default.

    https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work

    This workaround fixed the problem for me, although not for IE 10 and previous: Add the following code after any super call.

    if (Object.setPrototypeOf) {
      Object.setPrototypeOf(this, XHRError.prototype);
    } else {
      this.__proto__ = XHRError.prototype;
    }