6.2Express troubleshooting
The essentials in 30 seconds
- Reflex: one symptom = likely causes = one targeted action — diagnose before relaunching.
- Loop: a server that freezes or crashes almost always points to asynchronous code or unhandled errors.
- Production: any gap between local and production is handled with containers, environment variables and logs.
Salim thread — the playbook taped next to the screen
Salim keeps this playbook next to his screen. Verdict after one year: three lines served him most — the undefined from a result not yet ready, the server freezing under several users, and the secret that nearly went into Git. For each, he ended up applying the sequence (check, fix the cause, test) instead of relaunching at random.
Observed symptom, verified causes, actions in order: the reflex holds in three steps.
Diagnose before relaunching
A Node problem is rarely solved at random: each symptom has typical causes and one targeted action. The table below groups the most frequent situations, from asynchronous code to deployment.
| Symptom | Likely causes | Actions |
|---|---|---|
| I get undefined instead of my result | poorly handled asynchronous code: the result is not ready on the next line | use await (async function) or .then(); think “when it is ready”; wrap in try/catch (1.2) |
| UnhandledPromiseRejection / the server crashes | unhandled rejected promise; no centralised error handling | wrap await in try/catch; centralised error middleware (err, req, res, next); handle the 'error' event (4.4) |
| The server “freezes” as soon as there are several users | synchronous operation (fs.*Sync) or heavy CPU computation blocking the event loop | switch to async (fs.promises); offload CPU to worker threads; never block the loop (2.1/5.2) |
| Cannot find module / import error | wrong path, missing node_modules, CommonJS / ESM confusion | npm install; check ./ for local vs name for npm; require vs import consistency ('type':'module') (1.3) |
| req.body is undefined in Express | missing parsing middleware or placed after the routes | add app.use(express.json()) BEFORE the routes; check the Content-Type (3.1) |
| Duplicates or inconsistent data in the database | no constraint or validation; no lookup before creation | validated schema (required, unique); find then create/update; link rather than duplicate (3.3) |
| Potential flaw: injection / untrusted data | concatenating inputs into a query; unvalidated inputs | parameterised queries or ORM; validate inputs (Zod/Joi); never trust the client (3.4/4.2) |
| My API is slow under load | unoptimised queries (N+1, no index); no cache; a single core used | profile BEFORE touching; index and optimise queries; cache (Redis); clustering (PM2) (5.2) |
| “It works on my machine” but not in production | different environment (Node version, dependencies, configuration) | containerise (Docker); config via environment variables; check versions (5.3) |
| A secret leaked (key/API in code or Git) | plain-text secret in code or versioned | regenerate the key immediately; move to an environment variable (.env ignored by Git); never version .env (1.4/4.2) |
Ready-to-say script — diagnosing without relaunching at random (30 s)
«My symptom: [undefined / crash / freeze / empty body / slowness / prod gap]. I check the logs, identify the likely cause from the playbook, apply the targeted action and verify.»
Copy-paste template — express failure sheet
// Outage sheet: await + try/catch + error middleware
async function chargerTache(id) {
try {
const tache = await trouverTache(id);
return tache;
} catch (erreur) {
throw new Error("Read failed");
}
}
function gestionErreurs(err, req, res, next) {
console.error(err.message);
res.status(500).json({ erreur: "Internal error" });
}
module.exports = { chargerTache, gestionErreurs };
VSE / small budget
No formal table: one symptom, the likely cause from the playbook, the action and the owner noted.
SME Algeria
Fold local realities into the diagnosis: installed versions, shared machines, known activity peaks.
Remote / hybrid
Add immediate written logs to the actions: at a distance, an unrecorded symptom looks like a system that works.
Intercultural
Spell out findings in writing: what seems obvious (which version, which environment) is not obvious to everyone.
48h challenge — apply tomorrow
Spot 1 current symptom (undefined, freeze, empty body, slowness), fill in the express failure sheet and test the 1st action (logs + targeted fix).
- I can link a symptom to its likely causes.
- I filled in (or scheduled) an express failure sheet.
- I know the cross-reference to the level to dig into for my case.
Salim's server freezes as soon as several users connect. Which reflex does the playbook apply?
A recurring symptom is not ten failures: it is a missing reflex to anchor (await + try/catch, never Sync on a server, parsing before routes, validation, .env).