Network and API Debugging
Many JavaScript applications depend on APIs.
When data does not load or a form does not submit, the bug might be in frontend code, request configuration, server behavior, authentication, CORS, or the response format.
The Network panel helps you separate those possibilities.
First Question: Did the Request Happen?
Open DevTools and go to the Network panel.
Trigger the action again.
Look for the request.
If there is no request, the problem may be before the network layer:
- the event handler did not run
- the form submitted and reloaded the page
- a condition skipped the fetch call
- JavaScript crashed earlier
- the wrong button or element has the listener
Use the Console and breakpoints to confirm the code path.
Check the URL
A small URL mistake can cause a large bug.
fetch("/api/users/42");Check:
- path
- query string
- protocol
- domain
- port
- trailing slashes if the API cares about them
For query strings, prefer URLSearchParams.
const params = new URLSearchParams({
status: "active",
page: "1",
});
const response = await fetch(`/api/users?${params}`);This avoids broken URLs when values contain spaces, &, ?, or other special characters.
Check the Method
APIs often require a specific HTTP method.
await fetch("/api/users/42", {
method: "PATCH",
});Common method meanings:
| Method | Common use |
|---|---|
GET |
Read data |
POST |
Create data or submit an action |
PATCH |
Update part of a resource |
PUT |
Replace a resource |
DELETE |
Delete a resource |
If the method is wrong, the server may return 404, 405, 400, or another error.
Check Status Codes
The status code tells you how the server responded.
Common examples:
| Status | Meaning |
|---|---|
200 |
OK |
201 |
Created |
204 |
Success with no body |
400 |
Bad request |
401 |
Not authenticated |
403 |
Authenticated but not allowed |
404 |
Not found |
409 |
Conflict |
422 |
Validation error |
500 |
Server error |
Remember that fetch() does not reject for normal HTTP error statuses.
const response = await fetch("/api/users/42");
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}Check Request Headers
Headers describe the request.
For JSON request bodies, send Content-Type.
await fetch("/api/users", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ name: "Maya" }),
});For APIs that return JSON, you may also send Accept.
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
}For protected APIs, inspect the authorization header.
headers: {
Authorization: `Bearer ${token}`,
}Never paste real tokens into shared bug reports or screenshots.
Check the Request Body
In the Network panel, inspect the payload.
Common request body mistakes:
- sending an object instead of JSON text
- forgetting
JSON.stringify - sending fields with the wrong names
- sending
undefinedvalues - using the wrong content type
- accidentally submitting an empty form
Bad:
body: { name: "Maya" }Good:
body: JSON.stringify({ name: "Maya" })Check the Response Body
The response body often explains the failure.
{
"message": "Email is already taken"
}Handle error bodies deliberately.
async function readErrorMessage(response) {
const text = await response.text();
if (!text) {
return `Request failed with ${response.status}`;
}
try {
const data = JSON.parse(text);
return data.message || `Request failed with ${response.status}`;
} catch {
return text;
}
}This helps when the server sometimes returns JSON and sometimes returns plain text.
Debugging CORS
CORS errors happen when the browser blocks frontend JavaScript from reading a cross-origin response.
The Console may show a CORS message, and the Network panel may show the request.
Important points:
- CORS is enforced by the browser.
- CORS permission comes from server response headers.
mode: "no-cors"is usually not a real API fix.- A development proxy can help during local development.
If a request works in a server-side tool but fails in the browser, CORS may be involved because server-side tools do not enforce browser CORS rules.
Debugging Authentication
Authentication bugs often show up as 401 or 403.
Check:
- Is the token present?
- Is the token expired?
- Is the header name correct?
- Does the API expect cookies instead of bearer tokens?
- Are credentials included when cookies are needed?
For cookie-based auth, you may need:
await fetch("/api/account", {
credentials: "include",
});Only use credentials when the API and security model require it.
Debugging Slow Requests
The Network panel shows timing information.
Slow requests may be caused by:
- server processing
- large response bodies
- slow network
- duplicate requests
- missing caching
- requests made sequentially when they could be parallel
Before optimizing code, confirm which request is actually slow.
Common Mistakes
Do not debug API problems only from catch.
try {
await fetch("/api/users");
} catch (error) {
console.error(error);
}This catches network-level failures, but it does not catch 404 or 500 unless you check response.ok.
Do not assume an empty response can be parsed as JSON. A 204 No Content response has no body.
Do not expose tokens or private data in screenshots, logs, or shared examples.
Do not guess whether the frontend or backend is wrong. Inspect the request and response.
Summary
Network debugging is evidence-based.
Check:
- whether the request happened
- URL and method
- status code
- headers
- request body
- response body
- CORS messages
- authentication details
- timing and duplicate requests
The Network panel turns vague API failures into specific facts.