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
We're Expedited Security. We help SAAS applications prevent and recover from attack, overcome regulatory or integration security requirements or just stop "weird" traffic before it becomes a problem.

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?

an image

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.