Should a Promise.reject message be wrapped in Error?

12,598

Yes, it most definitely should. A string is not an error, when you have errors usually it means something went wrong which means you'd really enjoy a good stack trace. No error - no stack trace.

Just like with try/catch, if you add .catch to a thrown rejection, you want to be able to log the stack trace, throwing strings ruins that for you.

I'm on mobile so this answer is rather short but I really can't emphasize enough how important this is. In large (10K+ LoC) apps stack traces in rejections really made the difference between easy remote bug hunting and a long night in the office.

Share:
12,598

Related videos on Youtube

Dominic
Author by

Dominic

Premature abstraction is the root of all evil. I'm interested in JS, WASM, Rust, Go, blockchain. Pet peeve: People who ask for help but can't be bothered to take the time to write/format a decent question.

Updated on June 06, 2022

Comments

  • Dominic
    Dominic almost 2 years

    Using the native (ES6) Promise. Should I reject with an Error:

    Promise.reject(new Error('Something went wrong'));
    

    Or should I just reject with a string:

    Promise.reject('Something went wrong');
    

    And what is the difference in browser behaviour?

    • Felix Kling
      Felix Kling over 9 years
      I don't think there is a difference. You simply reject with a value. What that value is and how it is supposed to be processed depends on your application.
    • CodingIntrigue
      CodingIntrigue over 9 years
      @FelixKling MDN does say For debugging purposes, it is useful to make reason an instanceof Error - it doesn't however say why, any ideas?
    • Felix Kling
      Felix Kling over 9 years
      @RGraham: Where does it say that?
    • CodingIntrigue
      CodingIntrigue over 9 years
      Sorry, on the docs page for Promise.reject
    • Felix Kling
      Felix Kling over 9 years
      @RGraham: Probably for the reason Benjamin mentions in his answer, to get a stack trace. However, that's a characteristic of Error, not of passing an Error object to .reject(). The browser or JavaScript still doesn't care what you pass to .reject().
    • Benjamin Gruenbaum
      Benjamin Gruenbaum over 9 years
      Just like you can throw strings, but shouldn't.
    • jib
      jib almost 9 years
      You should use new: Promise.reject(new Error('Something went wrong'));
    • jib
      jib almost 9 years
      Also, in practice, just throw new Error('Something went wrong')); because inside promise-chains and Promise constructor executor functions, this turns into a rejection.
    • Bergi
      Bergi over 8 years
  • Dominic
    Dominic over 9 years
    Thanks I am also working on large apps glad that someone has had some practical experience with it
  • Benjamin Gruenbaum
    Benjamin Gruenbaum over 9 years
    In all honesty? Consider Bluebird, it has better stack traces, typed catch, and unhabdled rejection tracking which are all killer features for debugging. ES6 promises work well so far only in Firefox in our experience.
  • Benjamin Gruenbaum
    Benjamin Gruenbaum over 2 years
    2022 update: Don't prefer bluebird, all the changes for debugging have been upstreamed to native promises. (Errors should 100% be wrapped in new Error())