Quick-reference recipe card - copy-paste ready.
import express from "express" ;
import { Pool } from "pg" ;
const pool = new Pool ({ connectionString: process.env. DATABASE_URL , max: 10 });
const app = express ();
// BUG: client never released if query throws before release in wrong order
app. get ( "/orders-bug/:id" , async ( req , res ) => {
const client = await pool. connect ();
const result = await client. query ( "SELECT * FROM orders WHERE id = $1" , [req.params.id]);
if ( ! result.rows[ 0 ]) {
// forgot client.release() on early return - pool exhausts over time
return res. status ( 404 ). json ({ error: { code: "NOT_FOUND" } });
}
client. release ();
res. json ({ data: result.rows[ 0 ] });
});
// FIX: try/finally always releases
app. get ( "/orders/:id" , async ( req , res , next ) => {
const client = await pool. connect ();
try {
const result = await client. query ( "SELECT * FROM orders WHERE id = $1" , [req.params.id]);
if ( ! result.rows[ 0 ]) return res. status ( 404 ). json ({ error: { code: "NOT_FOUND" } });
res. json ({ data: result.rows[ 0 ] });
} finally {
client. release ();
}
});
// BUG: missing await - fire and forget, errors unhandled
app. post ( "/notify-bug" , ( req , res ) => {
sendEmail (req.body.email); // returns Promise, not awaited
res. status ( 202 ). json ({ accepted: true });
});
async function sendEmail ( to : string ) {
await new Promise (( r ) => setTimeout (r, 100 ));
if ( ! to. includes ( "@" )) throw new Error ( "invalid email" );
}
// FIX
app. post ( "/notify" , async ( req , res , next ) => {
try {
await sendEmail (req.body.email);
res. status ( 202 ). json ({ accepted: true });
} catch (err) {
next (err);
}
});
Stack versions: This page was written for Node.js 24.18.0 (Active LTS), npm 10+ , TypeScript 5.6+ , Express 5 , Fastify 5 , and NestJS 11 .