Request Context
Request context answers the basic operational questions around a failure: which route broke, which method hit it, and whether a request identifier can tie the incident back to server logs or traces.
If you use one of the built-in middleware integrations, request context is attached automatically. The middleware reads the method, URL, and filtered headers from the incoming request and creates an async context that follows the request through its lifecycle.
import express from "express";
import errorcore, { expressMiddleware } from "errorcore";
errorcore.init({
service: "checkout-api",
transport: { type: "file", path: "./errors.ndjson" },
allowUnencrypted: true,
});
const app = express();
app.use(expressMiddleware());
// any error thrown inside a route handler now includes
// the request method, URL, and filtered headers
app.get("/orders/:id", async (req, res) => {
const order = await db.orders.findById(req.params.id);
if (!order) throw new Error("order not found");
res.json(order);
});Manual context
For code paths outside a framework (background jobs, queue consumers, scheduled tasks), use withContext to create a scope manually:
import errorcore from "errorcore";
errorcore.withContext(() => {
// errors thrown here are captured with a context scope,
// so IO and state reads are grouped into the same incident
processQueueMessage(message);
});What gets captured
Each request context records:
- request method and URL
- request ID (from
x-request-idorx-correlation-idheaders, if present) - filtered headers (sensitive headers are excluded by default)
- request body, if
captureRequestBodiesis enabled
Header filtering
The header filter is controlled by headerAllowlist and headerBlocklist in the SDK config. The defaults keep safe operational headers and drop anything matching sensitive patterns:
// allowed by default
// content-type, content-length, accept, user-agent,
// x-request-id, x-correlation-id, host
// blocked by default (regex match)
// authorization, cookie, set-cookie, x-api-key,
// x-auth-token, and anything containing auth, token,
// key, secret, password, or credentialYou can override these lists if your service needs different filtering:
errorcore.init({
service: "internal-api",
transport: { type: "file", path: "./errors.ndjson" },
headerAllowlist: ["content-type", "x-request-id", "x-tenant-id"],
headerBlocklist: [/authorization|cookie|secret/i],
allowUnencrypted: true,
});Keep the captured shape narrow. Context should identify the request, not mirror the full payload.