Production mode in Express Zod API enables important optimizations and security enhancements. It’s activated by setting the NODE_ENV environment variable to production.
The most important change is how error messages are handled. In production, server-side error details are generalized to prevent information disclosure.
In production mode, the defaultResultHandler, defaultEndpointsFactory, and LastResortHandler generalize server-side error messages:
// Development mode:throw new Error("Database connection failed on server db-01:5432");// Response: { status: "error", error: { message: "Database connection failed on server db-01:5432" } }// Production mode:throw new Error("Database connection failed on server db-01:5432");// Response: { status: "error", error: { message: "Internal Server Error" } }
Errors with 5XX status codes are generalized in production:
import createHttpError from "http-errors";// In production mode:createHttpError(500, "Something is broken");// Response: "Internal Server Error"createHttpError(503, "Redis is down");// Response: "Service Unavailable"// 4XX errors are still exposed:createHttpError(401, "Token expired");// Response: "Token expired"createHttpError(400, "Invalid email format");// Response: "Invalid email format"
Use the expose option in createHttpError() to control whether error messages are shown:
import createHttpError from "http-errors";// Always hide (even for 4XX):createHttpError(401, "Token expired", { expose: false });// Production: "Unauthorized"// Development: "Token expired"// Always show (even for 5XX):createHttpError(501, "We didn't make it yet", { expose: true });// Production: "We didn't make it yet"// Development: "We didn't make it yet"// Default behavior (expose based on status code):createHttpError(400, "Validation failed"); // Always exposedcreateHttpError(500, "Internal error"); // Hidden in production
// User errors (4XX) - safe to exposethrow createHttpError(400, "Email format is invalid");throw createHttpError(404, "Resource not found");throw createHttpError(409, "Email already exists");// Server errors (5XX) - hide in productionthrow createHttpError(500, "Internal error"); // "Internal Server Error" in production