CodeQL documentation

Missing await

ID: js/missing-await
Kind: problem
Severity: warning
Precision: high
Tags:
   - correctness
Query suites:
   - javascript-security-and-quality.qls

Click to see the query in the CodeQL repository

In JavaScript, async functions always return a promise object. To obtain the underlying value of the promise, use the await operator or call the then method. Attempting to use a promise object instead of its underlying value can lead to unexpected behavior.

Recommendation

Use the await operator to get the value contained in the promise. Alternatively, call then on the promise and use the value passed to the callback.

Example

In the following example, the getData function returns a promise, and the caller checks if the returned promise is null:

async function getData(id) {
  let req = await fetch(`https://example.com/data?id=${id}`);
  if (!req.ok) return null;
  return req.json();
}

async function showData(id) {
  let data = getData(id);
  if (data == null) {
    console.warn("No data for: " + id);
    return;
  }
  // ...
}

However, the null check does not work as expected. The return null statement on line 2 actually returns a promise containing the null value. Since the promise object itself is not equal to null, the error check is bypassed.

The issue can be corrected by inserting await before the promise:

async function getData(id) {
  let req = await fetch(`https://example.com/data?id=${id}`);
  if (!req.ok) return null;
  return req.json();
}

async function showData(id) {
  let data = await getData(id);
  if (data == null) {
    console.warn("No data for: " + id);
    return;
  }
  // ...
}

References