🔥Limited Offer: Get 50% OFFon AI & Full Stack Courses🔥
Back to JavaScript Notes
Topic #229

Async Debugging

Asynchronous Bugs

Asynchronous code can be more difficult to debug than synchronous code.

The code often executes later than expected, and several asynchronous operations may run at the same time.

This chapter shows techniques for finding and fixing common problems in asynchronous JavaScript.

This chapter shows practical ways to debug fetch(), promises, and async/await.

Note: Async debugging is about finding where the code stops. Then to find why it stopped.


Log Events

The easiest way to debug asynchronous code is to log when things happen.

Use console.log()

console.log("Before fetch");

const promise = fetch("fetch.txt");

console.log("After fetch");

Use a display function

myDisplayer("Before fetch");

const promise = fetch("fetch.txt");

myDisplayer("After fetch");

Note: console.log(), often display the current state of a Promise like: This information is provided by the debugging tool. It is not part of the JavaScript language.

Why can't JavaScript do the same?

There is no standard properties like:

  • promise.state
  • promise.status

They simply do not exist.

The state part of the Promise is not in its public API.


Async Bugs Can be Invisible

Async code often fails after your function has already returned.

This makes it feel like nothing happened.

Example

// Async function to download a file

async function loadText(file) {

  const response = await fetch(file);

  myDisplayer(response);

}

myDisplayer("Start");

// Try to load a missing file

loadText("missing.txt");

myDisplayer("Done");

Note: The Done message prints even if loadText() fails. This is because the fetch() fails later.


Rule 1: Always Handle Errors

Unhandled promise rejections confuse beginners.

Handle errors early and clearly.

Use try...catch to handle Promises.

Example

// Async function to download a file

async function loadData(file) {

  try {

    let response = await fetch(file);

    let data = await response.json()

    myDisplayer(JSON.stringify(data));

  } catch (error) {

    myDisplayer(error);

  }

}

// Call async function

loadData("customer.json")

Note: The code above catches network errors and JSON parsing errors. It does not catch HTTP errors like 404 (file not found).


Rule 2: Check response.ok

Fetch does not reject on HTTP errors like 404.

You must check response.ok.

Example

// Async function to download a file

async function loadData(file) {

  try {

    let response = await fetch(file);

    if (!response.ok) {

      console.log("HTTP Error:", response.status);

      return;

    }

    let data = await response.json()

    myDisplayer(JSON.stringify(data));

  } catch (error) {

    myDisplayer(error);

  }

}

Note: The code above separates HTTP errors from network errors. Most fetch bugs are not JavaScript bugs. They are URL and server response bugs.


Rule 3: Log the Right Things

Logging a promise is not the same as logging the data.

Log the response and status first.

Example

// Async function to download a file

async function loadData(file) {

  let response = await fetch(file);

  myDisplayer(response.status);

  myDisplayer(response.headers.get("content-type"));

}

Note: The above code tells you if the server returned what you expected.


Common Response Headers

Col 1 Col 2
Header Description
Content-Type Type of the response (text/html, application/json, etc.)
Content-Length Size of the response in bytes
Cache-Control How the response may be cached
Expires When the cached response expires
Last-Modified When the resource was last modified
ETag Resource version identifier used for caching
Date Time the server generated the response
Server Information about the web server
Access-Control-Allow-Origin CORS policy
Content-Encoding Compression used (gzip, br, etc.)

Use the Browser Network Tab

The Network tab is a panel in your Browser's Developer Tools.

It shows all network request made by your web page.

Note: It is one of the most useful tools for debugging asynchronous JavaScript because it lets you see exactly what is happening when your code uses fetch(), loads images, downloads JSON, or sends data to a server.

How to Use the Developer Tools:

  • Open a Website
  • Press F12, or
  • Right-click the page and select Inspect.
  • Then select the Network tab.
  • Refresh the page

The Network tab shows every request made by your application:

  • Which files were requested
  • Whether they succeeded
  • HTTP status codes
  • Download times

Example

const response = await fetch("customer.json");

Some Possible Results

Col 1 Col 2 Col 3 Col 4 Col 5
Name Status Type Size Time
customer.json 200 fetch 548 Bytes 134ms
customer.json 404 fetch
customer.json Failed

Note: This is much easier than trying to guess why fetch() failed.


Use Breakpoints

Modern browsers allow you to pause JavaScript execution.

While execution is paused, you can inspect variables, Promises, and the Call Stack.


Example

Example
const response = await fetch("demo.txt");

debugger;

const text = await response.text();

Note: When execution reaches debugger, DevTools pauses automatically.

Breakpoints on await

You can set breakpoints on await lines.

This lets you inspect values before and after async steps.

Example

async function loadData() {

  let response = await fetch("data.json");

  let data = await response.json();

  console.log(data);

}

Set a breakpoint on the first await line.

Step over and inspect response.


Common Async Errors

Warning: Forgetting await is the most common beginner mistake.

Example

async function loadData() {

  let response = await fetch("data.json");

  let data = response.json();

  console.log(data);

}

This logs a promise, not the JSON.

Example

async function loadData() {

  let response = await fetch("data.json");

  let data = await response.json();

  console.log(data);

}

Debugging Promise Chains

Promises can fail anywhere in the chain.

Add logs between steps to find where it fails.

Example

fetch("data.json")

.then(function(response) {

  console.log("Got response");

  return response.json();

})

.then(function(data) {

  console.log("Got data");

  console.log(data);

})

.catch(function(error) {

  console.log("Failed");

  console.log(error);

});

This shows which step is failing.


Understand Execution Order

Example

myDisplayer("Start");

setTimeout(function() {myDisplayer("Timer")},1000);

myDisplayer("End");

Debug Parallel Operations

Result

const customer = fetch("customer.json");

const products = fetch("products.json");

const news = fetch("news.json");
  • All three requests start immediately
  • The browser may finish them in any order
  • That is normal

Check response.ok

Many beginners forget this.

Wrong:

const response = await fetch("missing.txt");

const text = await response.text();

Better:

if (!response.ok) {

  console.log(response.status);

}

Handle Promise Rejections

Example

fetch("missing.txt")

.then(function(response){

  return response.text();

})

.catch(function(err){

  console.log(err);

});

Explain the difference between:

  • Rejected Promise
  • HTTP error

Use finally()

Example

showSpinner();

try {

  ...

}

finally {

  hideSpinner();

}

Note: Cleanup code belongs in finally().


Debugging HowTo

  • Add try...catch around awaited code.
  • Check both response.ok and response.status.
  • Use breakpoints on await lines.
  • Use the Network tab.

Debugging Checklist

  • Did the Promise resolve?
  • Did you forget await?
  • Did you check response.ok?
  • Is your code inside an async function?
  • Did the request appear in the Network tab?
  • Are errors reported in the Console?
  • Are you blocking the Event Loop?

Summary

  • Use console.log() to trace execution.
  • Inspect Promise objects while debugging.
  • Use try...catch to handle rejected Promises.
  • Use the browser's Network tab to inspect requests.
  • Set breakpoints to inspect variables and execution.
  • Check response.ok after every fetch().

Want to go beyond the notes?

Join CodingNow 2.0's JavaScript course — live mentorship, real projects, and 100% placement support.

Enroll Now — Free Demo Available

Async Debugging – FAQs

Quick answers about learning Async Debugging in JavaScript.

This free note from CodingNow 2.0 explains Async Debugging in JavaScript — concept, syntax and worked code examples you can copy, run and revise before interviews.
Yes. Every JavaScript topic on CodingNow 2.0, including Async Debugging, is 100% free with no signup required.
With focused practice, most students grasp Async Debugging in 1–3 days from these notes; pairing it with CodingNow 2.0's mentor-led course takes you to job-ready depth faster.
Use the code examples in this note, then ask doubts for free on the CodingNow 2.0 Community (/community) — expert instructors answer within 24 hours.
WhatsApp
Call NowEnroll Now