polygoat icon indicating copy to clipboard operation
polygoat copied to clipboard

to throw or not to throw

Open sonnyp opened this issue 8 years ago • 15 comments

I see ~~3~~ 2 different approaches

callback

Pros

  • Consistency between promise and callback styles
  • Make it easier to handles all errors, no need for try catch, protect users/consumers from DOS accidents

Cons

  • releases zalgo when the function is used with a callback but you can dezalgo that return cb
  function delay (time, cb) {
    return pg(function (done) {
      if (typeof time !== 'number') {
        return cb(new Error(time + ' is not a number'))
      }
      setTimeout(done, time)
    }, cb)
  }

  delay('123').then(fn) // does not throw, the promise will reject
  delay('123', fn) // does not throw, fn will be called with the error as first argument

Should polygoat dezalgo itself?

throw for callback, reject for promise

Pros

  • This is how Node.js core behaves (doesn't mean it's the right way though see cons)

Cons

  • Inconsistency (promise reject, callback throws)
  • Doesn't protect from accidental DOS if you do not handles exceptions for the callback version

  function delay (time, cb) {
    return pg(function (done) {
      if (typeof time !== 'number') {
        throw new Error(time + ' is not a number')
      }
      setTimeout(done, time)
    }, cb)
  }

  delay('123').then(fn) // does not throw, the promise will reject
  delay('123', fn) // throws

~~throw~~

EDIT: discard, promise creation shouldn't throw

Pros

  • works fine with with async/await

Cons

  • the general consensus is that promise creation should not throw
  function delay (time, cb) {
    if (typeof time !== 'number') {
      throw new Error(time + ' is not a number')
    }
    return pg(function (done) {
      setTimeout(done, time)
    }, cb)
  }

  delay('123').then(fn) // throws
  delay('123', fn) // throws

sonnyp avatar Apr 18 '16 10:04 sonnyp