Posted almost 2 years ago. Visible to the public. Repeats.

Javascript: Don't throw exceptions from async functions

TLDR: A function is hard to use when it sometimes returns a promise and sometimes throws an exception. When writing an async function, prefer to signal failure by returning a rejected promise.

The full story

When your function returns a promise ("async function"), try not throw synchronous exceptions when encountering fatal errors.

So avoid this:

Copy
function foo(x) { if (!x) { throw "No x given" } else return new Promise(function(resolve, reject) { ... }); } }

It's hard to handle errors when calling foo, since we need to handle both a synchronous throw and an asynchronous rejection. Look how much code we need to handle failures of the foo() above:

Copy
try { function onFulfilled() { ... } function onRejected() { // handle async failure } foo(x).then(onFulfilled, onRejected); } catch (e) { // handle synchronous failure }

Instead you should signal an error by returning a rejected promise:

Copy
function foo(x) { if (!x) { return Promise.reject("No x given") } else return new Promise(function(resolve, reject) { ... }); } }

Now your caller only needs to handle async failure:

Copy
function onFulfilled() { ... } function onRejected() { // handle async failure } foo(x).then(onFulfilled, onRejected);

Converting exceptions to rejected promises

Exception thrown in promise callbacks will automatically be caught and converted to a rejected promise instead. That means if you really want to throw from foo() (or if you're calling another function that throws) you can wrap your code into the callback of a resolved promise:

Copy
function foo(x) { var promise = Promise.resolve(); return promise.then(function() { if (!x) { throw "No x given" } else return new Promise(function(resolve, reject) { ... }); } }); }

This behavior is in all Promises/A+ compatible implementations like native promises, jQuery 3+ deferreds or Bluebird. Deferreds in jQuery 1 and 2 do not have this behavior.

Read more

Promise-based functions should not throw exceptions

Growing Rails Applications in Practice
Check out our new e-book:
Learn to structure large Ruby on Rails codebases with the tools you already know and love.

Owner of this card:

Avatar
Henning Koch
Last edit:
almost 2 years ago
by Henning Koch
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Henning Koch to makandra dev
This website uses cookies to improve usability and analyze traffic.
Accept or learn more