Skip to content

Debugging Front-End Async Applications

At the end of this class, you should be able to…

  • Identify common asynchronous issues in front-end JavaScript applications.
  • Utilize debugging tools in the browser, including console, network panel, and breakpoints for async code.
  • Apply error handling techniques to manage failed promises and API requests gracefully.
  • Analyze logs and network requests to diagnose and resolve async issues.

Additional Notes: Emphasize using examples with fetch + JSON Server to replicate real-world API debugging scenarios.


In-Class Demo Jan 2026 term

To run the coding demo, you need to have your Student Workbook open in Visual Studio Code.

  1. Open the terminal window and paste in the following.

    Run from the root of your repository
    pnpm dlx tiged --disable-cache --force DG-InClass/SDEV-1150-A04-Jan-2026/sk/lesson-18 ./src/lesson-18
  2. Walk through the steps in the ReadMe.md of the new lesson.


A db.json file is provided with a books collection (same theme as Lesson 15/18).

Start JSON Server:

Terminal window
npm run api-server
# or
npx json-server --watch db.json --port 3000

Verify that the routes are working as expected in the browser:

Keep this running while working in your project.

Open index.html. The page has:

  • A Load Books button to fetch and render books
  • A Quick Add form to POST a new book (title + author)
  • A list <ul id="bookList"> that renders results

You’ll notice odd behaviours (empty list, errors, “Promise” showing on the page, duplicate renders). That’s by design.

Follow this flow before changing any code:

  1. Open DevTools —> Network (if you are working in a browser other than Chrome, you should be able to find and update similar settings)
    • Enable Preserve log and Disable cache
    • Filter on Fetch/XHR
  2. Click “Load Books” button
    • What request was sent? URL? Status?
    • If 404/500, open the Response and Preview tabs
  3. Open DevTools —> Console
    • Any uncaught (promise) errors? Warnings?
  4. Open DevTools —> Sources
    • Click Pause on exceptions (and Pause on caught exceptions if needed)
    • Try “Load Books” again. Where does execution pause?
  5. Submit the “Add Book” form (no validation yet)
    • Check Network: is it POST /books? Status code? Body sent?

Bug A - Wrong endpoint (404)

Symptom: GET /book —> 404 (typo) Where: main.js in the ndpoint string Fix: Use the correct route: http://localhost:3000/books Why: JSON Server routes are pluralized collections by default. Spelling matters.

Bug B — Missing await (renders [object Promise] or nothing at all)

Symptom: UI shows “Promise” or doesn’t render data Where: main.js const books = fetchData(endpoint); used without await Fix:

const books = await fetchData(endpoint);

Why: fetchData() returns a Promise; you must await it.

Bug C — Not checking response.ok (silent failures)

Symptom: 404/500 still goes to json() and throws cryptic errors Where: utils.js fetch and post functions Fix:

const response = await fetch(url);
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
const data = await response.json();

Why: Always guard json() behind an ok check.

Bug D — Unhandled promise rejection

Symptom: Console warns about unhandled Promise rejection when API is down Where: main.js Async functions lacking try/catch Fix:

try {
// fetch...
} catch (error) {
console.error(error);
showError('Unable to reach the API. Is it running?');
}

Why: Async/await errors must be caught to avoid silent failures.

Bug E — Double-click race / duplicate renders

Symptom: Rapid clicks produce duplicate requests or conflicting states Where: main.js load button handler Fix:

Disable while in-flight, re-enable when done:

loadBtn.disabled = true;
try {
const books = await fetchData(endpoint);
...
} finally {
loadBtn.disabled = false;
}

Why: Prevent overlapping requests and non-deterministic UI.

Bug F — Wrong body or headers on POST

Symptom: 400 Bad Request or 500 Internal Server Error from JSON Server Where: utils.js post function Fix:

Ensure valid JSON and headers:

await fetch(endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json', },
body: JSON.stringify(payload),
});

Why: JSON Server requires Content-Type: application/json and a valid JSON body.

Complete the following, in order:

  1. Reproduce each bug (A–F) and capture proof in DevTools:
    • Network request + status
    • Console error message or pause stack
  2. Fix bugs A–F one by one.
  3. Add one more improvement of your choice:
    • Add a Delete button per list item (with optimistic UI or re-load)
    • Show a “No results” message when API returns []
    • Add basic retry (e.g., retry once on a network error)
    • Debounce the Load Books button to avoid rapid repeats
IssueCauseSolution
TypeError: Failed to fetchJSON Server not running/wrong portStart the server (npx json-server --watch db.json --port 3000)
CORS errorUsing file:// pathRun your page through vite (npm run dev)
Empty listAPI returned no dataCheck db.json contents
Error message shows on screenNetwork or code issueInspect console for detailed error
JSON parse errorCalling json() on non-2xx responseGuard with if (!res.ok) throw
Promise in UIMissing awaitconst data = await res.json()
Duplicate list itemsMultiple concurrent requestsDisable button during load; debounce

Once you’re done making your own custom updates to the project, stage your files, commit your work, and push to the remote repository.

  1. Open a terminal in VS Code
  2. Stage all updated and created files:
Terminal window
git add .
  1. Commit the changes:
Terminal window
git commit -m 'Lesson 18 Example'
  1. Push your changes to the remote workbook repository:
Terminal window
git push origin main