How to diagnose and troubleshoot JavaScript async/await issues
The only EV HTTPS provider that checks your company's identity before you pay. Get your EV cert in hours, not days.
July 12, 2021
Following why you should flatten your JavaScript and our guide to flattening your JavaScript, this is a quick guide to troubleshooting async/await issues. It's only four items because they're what we typically encountered when refactoring the CertSimple code to use await.
Symptom: you log a value and it's a Promise, rather than the object you expect.
> console.log(person.orders)
Promise {
undefined,
domain:
Domain {
domain: null,
_events: { error: [Function: debugDomainError] },
_eventsCount: 1,
_maxListeners: undefined,
members: [] } }
You forgot await
when you set person.orders
.
Symptom: something that isn't a syntax error is reported as a syntax error.
So you've got eslint (and eslint-must-use-await of course) and a random variable suddenly becomes a syntax error?
Does the variable name have an await
immediately beforehand? ESLint is actually complaining about a missing async
at the top of the function.
Symptom: promisify() doesn't work on a method
Sometimes node 8's util.promisify()
seemingly just doesn't work. Call a method regularly, it's fine, but promisify it and it starts producing strange errors.
For example, here's Bing API being promisified:
var searchBing = util.promisify(Bing.web);
After we use it, we'll get:
(node:1752) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): TypeError: this.searchVertical is not a function
Huh? searchBing
now doesn't work but we haven't done anything asides from promisify
it! The key is the this
in the error: JavaScript's promiscuous this
also affects promisifying. The fix is easy: just bind
then promisify
:
var searchBing = util.promisify(Bing.web.bind(Bing));
Thanks for this person on Stack Overflow for helping me out there.
Symptom: something just stops.
Calling a piece of code and it just... stops?
An async/await
refactor often goes like this:
- Start by wrapping your libraries in
util.promisify()
. - Refactor that code to remove callbacks and return Promises.
Which is reasonable. A common error is doing that and then forgetting to remove the original promisify()
- accidentally promisifying something that now already returns a promise.
The symptoms for this are simple: your code just stops at the double-promised function. The solution is also pretty simple: remove the no-longer-needed util.promisify()
.
That's all
We hope this has been useful. We expect there'll probably be some discussion on Hacker News too.