Good Code
The good version catches async failures at the HTTP boundary, logs context, and returns a single error response.
Lesson 03
Handle rejected promises at the boundary where you can return a useful response.
import type { ServerResponse } from "node:http";
import { createReport } from "../services/reports";
export async function sendReport(response: ServerResponse) {
try {
const report = await createReport();
response.setHeader("content-type", "application/json");
response.end(JSON.stringify({ report }));
} catch (error) {
console.error({ error }, "Could not create report");
response.statusCode = 500;
response.end(JSON.stringify({ error: "Could not create report." }));
}
}import type { ServerResponse } from "node:http";
import { createReport } from "../services/reports";
export function sendReport(response: ServerResponse) {
createReport().then((report) => {
response.setHeader("content-type", "application/json");
response.end(JSON.stringify({ report }));
});
}The good version catches async failures at the HTTP boundary, logs context, and returns a single error response.
The bad version never handles a rejected promise, so the process can emit an unhandled rejection while the client waits or disconnects.