Async/await is great. Makes your code easier to read 👌 But the error handling ... oof 🙄
Yes try catch is great, it might even make your code easier to read. Combined with JavaScript's modern block scoping it gives rise to the vile side of exception handling.
check this out 👇
Say you're using @lukeed05's httpie to scream at a server.
A post request to a naughty server. But the naughty server says no.
What do you do? Add a try catch. Wanna handle those JavaScript errors and show a message to the user.
You're talking to a naughty server and handling errors like you're supposed to. 👏
What about not errors? You can take the data and do something.
Oh no what just happened!? 😱
You're getting a "Naughty server said no" error even though you made the mistake. You can't just access properties on undefinedStuff. JavaScript doesn't like that.
Blaming the server for your mistakes, tsk
Oh I know! We can move using data to after the catch block, right? That should work.
Nope. Now data isn't defined because const { data }
only works within that try block. 🤦♂️
You could solve that with a var
, but that's old school JavaScript and we all agreed we'd stop using it.
Curated JavaScript Essays
Get a series of curated essays on JavaScript. Lessons and insights from building software for production. No bullshit.
What about this?
This works. But pre-declaring your variables like it's 1978? No thanks. That's why variable hoisting was invented in the first place, lol.
You could wrap your code in another level of try/catch ...
And that's never ever going to get out of hand is it? 😅
I'm gonna be honest with you: There's no solution. Not a nice one. Not in JavaScript.
Other languages let you catch specific error types. As far as I know, JavaScript doesn't (can't?) support that :/
We have stumbled upon the basic truth of exception handling
It sucks. It always sucks. Whichever way you do it, it's going to make your head spin.
You see there's 2 ways software can approach errors:
- Error passing
- Exceptions
Error passing
Error passing is what we used to do with JavaScript in the era of callbacks. Callbacks break try/catch for deep technical reasons so we stopped using them.
The logic behind error passing is simple: Every function can return an error, or a result.
Great in theory. Except now every function has to check for errors.. Our code looked like this:
1st argument out of a function is an error object, 2nd argument is the result. Check for errors, go into the error path, no errors, do the stuff.
Error handling spreads through your codebase like a virus.
All languages have this problem. Some on purpose, some by accident. I know Golang made the conscious decision to use error passing because exceptions are a mess and errors should be handled right away.
Luke proposes function wrappers to give your async/await code error passing superpowers.
Okay sir, I present to you: a sane solution:
— Luke Edwards (@lukeed05) February 6, 2019
First, the generic, reusable solution for just about anything.
I planned to release this at some point, but there are apparently lots on npm already.
Second, the `httpie` specific solution that you and @DavidKPiano requested 👇
Wrap anything (Promises, AsyncFunctions, functions, ...any) and receive it as:
— Luke Edwards (@lukeed05) February 6, 2019
👉 [err, data]
You don't have to reuse `err` and `data`, but IMO it's better than having err1, err2, ... data1, data2... etc pic.twitter.com/GpC4z9UP6Q
🤨 I'm not convinced but I guess
Exceptions "improve" error passing
Many moons ago someone had the bright idea that hey error passing sucks, let's use exceptions instead. Wikipedia says it was Lisp in the 1960s.
Something like this:
- Error handling sucks
- Passing errors around and staying vigilant at all times leads to bugs
- What if we had a sort of error context that handles it behind the scenes?
So instead of functions returning errors, they raise exceptions and hope for the best 🤞
When you raise an exception your code stops. The computer then goes back up through the entire call stack to find the nearest catch
block.
That catch block handles your error and execution continues from there. NOT from where the error was raised.
This is crucial. It means that 90% of the time you're writing happy path code and don't have to worry about errors.
And somewhere in your code you make sure to handle all errors.
For example that's how Ruby on Rails can make sure that no matter what you do, if all goes to shit, RoR itself will serve a beautiful 500 page telling the user what's up.
👌
Python does it great too. You never know what sort of error or exception some code might raise and you hope that someone somewhere will know how to handle it.
You focus on the good stuff.
JavaScript's missing exception piece
JavaScript's missing piece are exception types.
Take this Python code for example:
Beautiful ❤️
Write happy path code in one block, followed by a series of error handling code for different types of errors.
This works across function calls, across entire systems, it just works. It works really really well.
If you don't handle the error, it bubbles up the stack. Someone will handle it.
When all goes to shit, the Python environment itself runs your code in a try/except of sorts so it can print an error message. ✌️
What can you do?
Give up. You're already writing code. There's your first mistake 😛
Error handling is always going to suck. I'm sorry.
But you can emulate the python/ruby/java/etc approach in JavaScript and make your life a little easier. You'll have to coordinate with your team because there's no language support, but something like this might work:
Of course then you have to set myType
on every error you raise and that's tedious too 🤔
Sorry that's the best we can do. 🙈
Five things Friday
As promised last week, here's five cool things
The httpie library my favorite way to talk to servers from JavaScript. Really happy with it. Check out my twitter thread review of httpie
React Hooks are out. 🎣
Here's a good overview from SebHastian
You can also read my twitter thread about hooks where I get panned for Doing It Wrong. Fun times.
This isn't technical but it is amazing. @shl reflects on his failure to build a billion dollar company. Instead he built an amazing business that works. (Gumroad)
Michel Westrase whose name I can never spell right (he made MobX) writes a great article about UI as an afterthought
Enjoy your weekend ✌️
Cheers,
~Swizec
Continue reading about Async, await, catch – error handling that won't drive you crazy
Semantically similar articles hand-picked by GPT-4
- A promises gotcha that will catch you out
- Modern backend is a JavaScript function
- Waiting for Godot with callbacks, promises, and async
- TypeScript for serverless lambda backends 👌
- Livecoding Recap 48: JavaScript async/await and Morty's Mindblowers
Want to become a JavaScript expert?
Learning from tutorials is great! You follow some steps, learn a smol lesson, and feel like you got this. Then you go into an interview, get a question from the boss, or encounter a new situation and o-oh.
Shit, how does this work again? 😅
That's the problem with tutorials. They're not how the world works. Real software is a mess. A best-effort pile of duct tape and chewing gum. You need deep understanding, not recipes.
Leave your email and get the JavaScript Essays series - a series of curated essays and experiments on modern JavaScript. Lessons learned from practice building production software.
Curated JavaScript Essays
Get a series of curated essays on JavaScript. Lessons and insights from building software for production. No bullshit.
Have a burning question that you think I can answer? Hit me up on twitter and I'll do my best.
Who am I and who do I help? I'm Swizec Teller and I turn coders into engineers with "Raw and honest from the heart!" writing. No bullshit. Real insights into the career and skills of a modern software engineer.
Want to become a true senior engineer? Take ownership, have autonomy, and be a force multiplier on your team. The Senior Engineer Mindset ebook can help 👉 swizec.com/senior-mindset. These are the shifts in mindset that unlocked my career.
Curious about Serverless and the modern backend? Check out Serverless Handbook, for frontend engineers 👉 ServerlessHandbook.dev
Want to Stop copy pasting D3 examples and create data visualizations of your own? Learn how to build scalable dataviz React components your whole team can understand with React for Data Visualization
Want to get my best emails on JavaScript, React, Serverless, Fullstack Web, or Indie Hacking? Check out swizec.com/collections
Did someone amazing share this letter with you? Wonderful! You can sign up for my weekly letters for software engineers on their path to greatness, here: swizec.com/blog
Want to brush up on your modern JavaScript syntax? Check out my interactive cheatsheet: es6cheatsheet.com
By the way, just in case no one has told you it yet today: I love and appreciate you for who you are ❤️