Observability
onError(error, { phase, event }) receives every error the handler catches, once per error, with the phase it was caught in (request, middleware, api, rpc,…
onError(error, { phase, event }) receives every error the handler catches, once per error, with the phase it was
caught in (request, middleware, api, rpc, loader, render, stream, head); event.id is the id in the
x-request-id header of the response and in error.requestId of JSON error bodies. onWarning(message) receives
configuration warnings. A missing allowedHosts in production is one warning, sent on the first request (see
Running behind a proxy); allowedHosts: [] without acknowledgeNoHostCheck makes createHandler throw. Without onWarning the handler prints a [dusk] line with the
phase and request id, and the error, with console.error, and warnings with console.warn. renderHeader: true adds
x-dusk-render: stream (or async, string) to pages, to see which render mode answered.
import type { HandlerOptions } from "@shadow-js/dusk/server";
const log = (level: "error" | "warn", fields: Record<string, unknown>): void => {
process.stdout.write(`${JSON.stringify({ level, time: new Date().toISOString(), ...fields })}\n`);
};
const options: Omit<HandlerOptions, "manifest"> = {
security: { allowedHosts: ["localhost", "example.com"] },
onError(error, { phase, event }) {
log("error", {
phase,
requestId: event?.id,
method: event?.method,
path: event?.url.pathname,
message: error instanceof Error ? error.message : String(error),
stack: error instanceof Error ? error.stack : undefined,
});
},
onWarning: (message) => log("warn", { message }),
renderHeader: true,
};
export default options;