error-handlingiced-coffeescript

try catch not always works in iced coffee script


I use try catch block in iced coffee script. I call not existent method fake of not existent object a and expect to catch error.

db = require '../../call/db.iced'
try
    await db.find "79", defer c, d
    a.fake()
catch error
    console.log "error catched"
    console.log error

But after calling function db.find a.fake() throw error in console, but it don't use try catch block as expected.

If I comment out string await db.find "79", defer c, d...

db = require '../../call/db.iced'
    try
        # await db.find "79", defer c, d ############## commented out
        a.fake()
    catch error
        console.log "error catched"
        console.log error

... it works as expected and error is catched.

I tried to change string await db.find "79", defer c, d by other simple async functions calles but they works fine and error was catched well.

It is interesting that function db.find works good. When I comment out string a.fake()...

db = require '../../call/db.iced'
    try
        await db.find "79", defer c, d
        #a.fake() ################################ commented out
    catch error
        console.log "error catched"
        console.log error

... this script works without any errors and so without catching errors.

Can not figure out why I can not catch error after function await db.find "79", defer c, d.


Solution

  • The documentation states the following on try catch statements:

    The only exception is try, which doesn't catch exceptions when called from event handlers the main loop, for the same reason hand-rolled asynchronous code and try do not work well together.

    I suspect that since db.find is called asynchronously, the try construct remains with the db.find thread and does not stay in the main thread. This would result in the findings you describe.

    One crude solution is to catch both function calls. However, I think the proper way to use await is with the defer function. Check out the documentation for an explanation.

    Also, you might find the following helpful:

    Possible Solutions

    1. Place a try catch around both statements.

      try
          await db.find "79", defer c, d
      catch error
          console.log "error catched"
          console.log error
      try
          a.fake()
      catch error
          console.log "error catched"
          console.log error
      
    2. As described in the link above, place db.find outside the try catch and detect it's error another way.

      await db.find "79", defer err, id
      if err then return cb err, null
      
      try
          a.fake()
      catch error
          console.log "error catched"
          console.log error