0

I've created a custom exception error class, BookingError, that is supposed to handle all booking-related errors that are thrown:

class BookingError extends Error{
    constructor(message: string){
        super(message);
        this.name = "BookingError";
    }
}

When using this to throw exceptions, I've run into an issue where I cannot reliably check the instanceof against the class to decide what to do with the error.

const throwError = () => {
    throw new BookingError("This is a test.");
};

const testErrorException = () => {
    try{
        throwError();
    } catch(err: unknown){
        // This will always result in a false output.
        console.log(err instanceof BookingError);
    }
};

This code will result in the following:

Error [BookingError]: This is a test.

EDIT: Interestingly enough, albeit hacky, the following code will result in the expected output:

if((err as BookingError).name === "BookingError"){
    // This will output "This is a test."
    console.log((err as BookingError).message);
}
GROVER.
  • 4,071
  • 2
  • 19
  • 66
  • 3
    This gives me `true`. I tried it in [this playground](https://www.typescriptlang.org/play?#code/MYGwhgzhAEBCD28DWBLAdgcwKICcfx2gFMAPAFyLQBMZd8cBvAKGlemHjQjJwFdgyBABQBbIlDAYiALmjcc6DAEpmbNXN4AHIjlHiIkokoDcLdazIALFBAB0aMGOgBeaACIEyRXQJvTagF8mIKYOLjJoK3wAdx9CVyElFwA+aFU2KPho6DQibM9UTDihNwAVaxgbaDBI8TJbNxNg01DOblruOKwSYCJNMhROF2hElLSzCxwAT3TzTNi8YSbA9jAyYEshHRwVCfUAen3ocqrolBAQapBosCmYHHFeEAj0augAMzAQCCJoeF4yJoAbY9mowhB4CAiLYQPAMFs8NB0NwwGhevB3nBEIVsIsdv42EEAi0KJ08d1ev1BmhEsYgA) – Shri Hari L Jun 14 '23 at 05:33
  • 1
    Could you please include a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) in which it outputs as `false`, probably in a playground? – Shri Hari L Jun 14 '23 at 05:36
  • @ShriHariL All relevant information from my codebase is included. – GROVER. Jun 14 '23 at 05:37
  • If so, then shall we print `console.log(err)` to debug the object instance. – Shri Hari L Jun 14 '23 at 05:40
  • @ShriHariL The result of `console.log(err)` is `Error [BookingError]: This is a test.` – GROVER. Jun 14 '23 at 05:41
  • You might have multiple instances of `BookingError`, are you using a package manager, having incorrect versioning can cause this. What module loader / bundler are you using?, Or are you using pure ES modules. – Keith Jun 14 '23 at 06:14
  • Also try doing a full search of you app, make sure you have just not defined this class in multiple units. Lastly, are you using it between webworkers / cluster etc, as instance won't be the same between threads.. – Keith Jun 14 '23 at 06:19
  • @Keith `BookingError` is only declared once in the entire app :) – GROVER. Jun 14 '23 at 06:20
  • `EDIT: Interestingly enough,` Yes, doing that helps when you have multiple class definitions. Were or how your getting this is hard to tell. One idea though is place a `console.log('create BookingError')` just before the `class BookingError extends...`, see if you get more than 1 console log. – Keith Jun 14 '23 at 06:42
  • Multiple instances of a class definition can be a pain to track down, it was common for React apps to fail for this very reason, and the reason React has built-in support to check for this. Often semantic versioning was incorrectly setup up etc, and you could end up with say version `16.0.0.1` & `16.0.0.2` been installed, and yes, just something as simple as that would cause React to fail. – Keith Jun 14 '23 at 06:50
  • 1
    If your transpiling to es5 or below this will fail. https://www.typescriptlang.org/play?target=1#code/MYGwhgzhAEBCD28DWBLAdgcwKICcfx2gFMAPAFyLQBMZd8cBvAKGlemHjQjJwFdgyBABQBbIlDAYiALmjcc6DAEpmbNXN4AHIjlHiIkokoDcLdazIALFBAB0aMGOgBeaACIEyRXQJvTagF8mIKYOLjJoK3wAdx9CVyElFwA+aFU2KPho6DQibM9UTDihNwAVaxgbaDBI8TJbNxNg01DOblruOKwSYCJNMhROF2hElLSzCxwAT3TzTNi8YSbA9jAyYEshHRwVCfUAen3ocqrolBAQapBosCmYHHFeEAj0augAMzAQCCJoeF4yJoAbY9mowhB4CAiLYQPAMFs8NB0NwwGhevB3nBEIVsIsdv42EEAi0KJ08d1ev1BmhEsYgA – Aluan Haddad Jun 14 '23 at 06:56
  • 1
    @AluanHaddad Ah, yes. To fix you would need to correct the prototype -> `(this as any).__proto__ = BookingError.prototype;`. But to be fair in this day and age I would say it's pretty safe to set target minimum to `ES2015` , – Keith Jun 14 '23 at 07:30
  • 1
    @Keith Indeed that's true, but as per several of your previous comments there are other reasons to avoid relying on `instanceof` in JS. – Aluan Haddad Jun 14 '23 at 07:34

0 Answers0