Skip to content

Instantly share code, notes, and snippets.

@coolaj86
Last active Sep 8, 2021
Embed
What would you like to do?

The Await Catch Pattern

await-catch-thumb

See Also:

See https://github.com/therootcompany/async-router

Async / Await is Ugly

try {
    let results;
    try {
        results = await ProfileModel.get(req.user.id);
    } catch (err) {
        if ("E_NO_RECORD" !== err.code) {
            throw err;
        }
        results = Profile.create();
    }
    res.json(await doStuff(results));
} catch (e) {
    next(err);
}

Promise Chains are Clean

return ProfileModel.get(req.user.id)
    .catch(function (err) {
        if ("E_NO_RECORD" !== err.code) {
            throw err;
        }
        return Profile.create();
    })
    .then(function (results) {
        return doStuff(results).then(res.json);
    })
    .catch(next);

Await Catch is Elegant

let results = await ProfileModel.get(req.user.id)
    .catch(function (err) {
        if ("E_NO_RECORD" !== err.code) {
            throw err;
        }
        return Profile.create();
    });

res.json(await doStuff(results));
@coolaj86

This comment has been minimized.

Copy link
Owner Author

@coolaj86 coolaj86 commented Jul 20, 2021

Assertions:

  • 😎 Clean Code reads top to bottom ⬇️

  • Ugly Code reads left to right ➡️

  • 🥴 Atrocious Code reads left to right ➡️ to bottom to top ⬆️

  • try / catch is a code smell 👃

  • 👹 try / await is code hell

  • await / catch is elegant 😇

@jsmart523

This comment has been minimized.

Copy link

@jsmart523 jsmart523 commented Aug 31, 2021

Thanks! Good pattern!

But shouldn't your ugly solution call next(e) and ...assuming res.json doesn't return a promise... your elegant solution be the following??

try {
let results = await ProfileModel.get(req.user.id)
    .catch(function (err) {
        if ("E_NO_RECORD" !== err.code) {
            throw err;
        }
        return Profile.create();
    });

res.json(await doStuff(results));
} catch (e) {
    next(e);
}
@coolaj86

This comment has been minimized.

Copy link
Owner Author

@coolaj86 coolaj86 commented Sep 1, 2021

@jsmart523: Yes, and no. You could swap

throw err;

for

next(err);
return;

But try/catch is a nasty code smell... about as bad as the sulfur burps I'm having today... yuck!

Take a look here, and never try / catch in express routes again:
https://github.com/therootcompany/async-router

@jsmart523

This comment has been minimized.

Copy link

@jsmart523 jsmart523 commented Sep 1, 2021

Hmmm .. but that wouldn't catch errors from res.json(await doStuff(results));, right? Or am I misunderstanding you?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment