Module 42: Web Servers with Express
Requests and responses in practice
🏠The everyday picture
A good counter clerk always gives a receipt, says clearly why something was refused, and never shows customers the mess behind the counter.
📘What it really is
-
Always send exactly one response per request. Forgetting to respond leaves the browser waiting until it gives up; responding twice causes the error "Cannot set headers after they are sent". Use
return res.status(...).json(...)to stop after responding. -
Consistent error responses, so the frontend can rely on them:
{ "error": "Enquiry not found" }
{ "error": "Validation failed", "fields": { "email": "Please enter a valid email." } }
-
Status codes to use (Module 25): 200, 201, 204 for success; 400 or 422 for bad input; 401, 403, 404; 500 for the server's own failures.
-
Async handlers: Express 5 passes errors from
asynchandlers to the error handler automatically (Module 43). In older Express 4 code (common in AI answers), you'll see wrappers ortry/catchin every route. -
Never send internal details in responses: no stack traces, file paths, or database errors to the client. Log them; send a short message (Module 48).
-
Typing requests:
Request<{ id: string }>givesreq.params.ida type. Bodies are stillunknownuntil validated, whatever their type says.
🖱️Try it
Make every route return consistent JSON errors. Add a deliberate throw new Error("boom") in one route and see what
the client receives by default (Express sends an HTML error page). You'll fix this properly with an error handler in
Module 43.
✅Quick check
A route handler forgets to send a response in one branch. What does the client experience?
Show the answer
The request hangs until it times out.
Why not send the stack trace to the client when something fails?
Show the answer
It reveals internal details that can help attackers, and means nothing to users. Log it instead.
