Summary
Unhandled exceptions must not expose internal details to API clients.
The current pattern returns a generic response in some controllers. It does not provide a consistent final error boundary. Express can return a stack trace when an error reaches its default error handler. The application also needs a safe way to correlate a client error with a reproducible Kiroo capture.
Use @kiroo/sdk for request/response replay IDs. Do not use Kiroo as the only production error log. Kiroo captures the request and response. It does not capture the JavaScript stack trace.
Kiroo prerequisite
Release a Kiroo version that meets these requirements before this application uses Kiroo captures in production.
- Redact sensitive values in all captured locations:
- request headers;
- response headers;
- request-body fields;
- response-body fields;
- URL query parameters.
- Preserve recursive, case-insensitive redaction for object keys.
- Provide configuration for application-specific redaction:
redactKeys;
redactHeaders;
redactQueryParams;
- a custom redaction callback, if supported.
- Include safe default redaction for credential fields and common personal-data fields.
- Sanitize response headers before Kiroo stores them.
@kiroo/sdk 0.1.2 stores res.getHeaders() without sanitization.
- Document that the Supabase bucket must be private, that capture access must be restricted, and that retention must meet the application's privacy policy.
- Document that Kiroo does not capture a JavaScript stack trace. The application must keep stack traces in protected server-side logs.
- Update the Kiroo error example. It must not return internal error text such as
"Downstream timeout" to a client.
- Add tests for nested fields, case variants, query parameters, request headers, and response headers.
@kiroo/sdk 0.1.2 already provides an X-Kiroo-Replay-ID header and captures all responses with status >=400, even when sampleRate is 0.
Application changes
- Register a final Express error-handling middleware after all routes.
- Log the error, stack trace, HTTP method, route, and Kiroo replay ID to protected server-side logs.
- Return a generic
500 response for unexpected errors.
- Include the Kiroo replay ID in the generic error response.
- Do not return
err.message, err.stack, database errors, upstream error payloads, or internal file paths.
- Keep Kiroo capture middleware before routes and the final error handler.
- Configure
sampleRate: 0 if the application must capture only error responses. Kiroo still captures status codes >=400.
Example response shape:
const replayId = res.get("X-Kiroo-Replay-ID");
res.status(500).json({
success: false,
message: "Internal server error",
data: { replayId }
});
Debugging workflow
- A client receives a generic error response and
replayId.
- The operator locates the protected server-side error log by
replayId.
- The operator uses the replay ID with Kiroo to fetch and replay the sanitized request locally.
- The operator uses the protected server-side log for the stack trace.
Acceptance criteria
- API clients never receive stack traces or unexpected internal error details.
- The final Express error handler handles errors that reach it.
- Each error response contains the Kiroo replay ID.
- Production logs contain the stack trace and the same replay ID.
- Kiroo captures redact the configured credentials and personal data from bodies, headers, and URL query parameters.
- Kiroo storage is private and has documented retention and access controls.
- Tests cover the final error handler and Kiroo redaction behavior.
Summary
Unhandled exceptions must not expose internal details to API clients.
The current pattern returns a generic response in some controllers. It does not provide a consistent final error boundary. Express can return a stack trace when an error reaches its default error handler. The application also needs a safe way to correlate a client error with a reproducible Kiroo capture.
Use
@kiroo/sdkfor request/response replay IDs. Do not use Kiroo as the only production error log. Kiroo captures the request and response. It does not capture the JavaScript stack trace.Kiroo prerequisite
Release a Kiroo version that meets these requirements before this application uses Kiroo captures in production.
redactKeys;redactHeaders;redactQueryParams;@kiroo/sdk0.1.2storesres.getHeaders()without sanitization."Downstream timeout"to a client.@kiroo/sdk0.1.2already provides anX-Kiroo-Replay-IDheader and captures all responses with status>=400, even whensampleRateis0.Application changes
500response for unexpected errors.err.message,err.stack, database errors, upstream error payloads, or internal file paths.sampleRate: 0if the application must capture only error responses. Kiroo still captures status codes>=400.Example response shape:
Debugging workflow
replayId.replayId.Acceptance criteria