Skip to content

Instantly share code, notes, and snippets.

@coolaj86
Last active September 8, 2021 15:30
Show Gist options
  • Save coolaj86/442925c20c6f13c6362b4af690a7f636 to your computer and use it in GitHub Desktop.
Save coolaj86/442925c20c6f13c6362b4af690a7f636 to your computer and use it in GitHub Desktop.

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
Copy link
Author

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
Copy link

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
Copy link
Author

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
Copy link

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