Okay, this has an interesting execution path:
- .queryAsync experiences an error. Since it's promise-based, it skips over the .then function, and hits .catch.
- .catch calls the callback with the error.
- The callback provided in the test checks for an error, and throws it. This ends the callback function, and passes control back to .catch.
- .catch doesn't have any try/catch handlers inside of it, so the thrown error propagates up to the Promise code, which catches it.
- There is no more error handling after .catch, so bluebird detects that the thrown error was never caught and logs it (by default)
Does that make sense? This is conceptually similar to rethrowing an error from inside of a synchronous catch statement. .catch will handle any error that was thrown in the promise chain before it, but if you throw something inside of .catch, the resulting promise will be be rejected once more.
As an aside, there's a lot of switching back and forth between callbacks and promises in the above code; is that intentional? If you're defining your own API, you may consider making the run function return a promise instead of asking for a callback. I'd do something like this:
module.exports.run = function(event, context) {
return myclass.queryAsync(...)