Should I completely eliminate try/catch from code where I use (Bluebird) promises?

147 Views Asked by At

I have a couple very basic setup steps before I call my promisified functions and I am considering wrapping them in a try/catch block because that seems the simplest way. However, it seems a little dirty to me.

Should I instead make a function that returns a Promise, even if it is very simple? Here is an example.

try
  thingyId = req.params.id # here I am 99.999% sure that params is defined,
  # but if for some bizarre reason it's not, I'd like to handle that error
  # instead of breaking the whole program
catch
  console.log "error: " + e

# do normal promisified functions

or should I write this as

setThingyId = (req) ->
  return new Promise (resolve, reject) !->
    if req.hasOwnProperty "params"
      resolve req.params.id
    else
      reject new Error "no params"

setThingyId(req)
  .then (deviceId) ->
    # other promisified functions
1

There are 1 best solutions below

2
On BEST ANSWER

Well - that's actually a good question.

  • If a function is synchronous - do NOT return a promise and do NOT utilize bluebird in it. It is slower than synchronous execution and harder to debug. Using try/catch for synchronous code is very appropriate. You could instead of course perform the "params" in req in an if instead of using exceptions at all which is likely more appropriate.

  • If a function completes its task in an asynchronous manner and returns a promise, you can use Promise.method to make it throw safe.

So in your case I'd do:

setThingyId = (req) ->
    if req && req.params && req.params.id
       someCalculationOverReqId req.params.id
    else 
       handleExceptionalCase req

Here's Promise.method:

setThingyId = Promise.method (req) ->
    someCalculationOverReqId req.params.id

Note that this only makes sense if the function returns a promise, what this will do is turn any throws to rejections effectively making the function throw safe.