feat: onError always logs, onResponse logs status+time, fix debug

onError: always log.error regardless of status code.
onResponse: log info with response status + duration in ms.
claimPairing: debug changed to info (debug not working in BSB).
Timestamps tracked via _startMs on event context.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mitchell R 2026-05-26 01:41:16 +02:00
parent 85f8456cf0
commit 4880dc32fc
No known key found for this signature in database
3 changed files with 27 additions and 49 deletions

View file

@ -206,37 +206,26 @@ export class Plugin extends BSBService<InstanceType<typeof Config>, typeof Event
});
reqObs.log.info("{method} {path}", { method, path });
event.context.obs = reqObs;
(event.context as any)._startMs = Date.now();
},
onError: (error, event) => {
const reqObs = event.context.obs;
const status = error.status ?? 500;
const path = event.req.url ?? "unknown";
const err = error.message ?? String(error);
if (!reqObs) {
obs.log.error("HTTP {status} {path}: {err} (no request trace)", {
status,
path,
err: error.message ?? String(error),
});
obs.log.error("HTTP error {path}: {err} (no request trace)", { path, err });
return;
}
if (status >= 500) {
reqObs.log.error("HTTP {status} {path}: {err}", {
status,
path,
err: error.message ?? String(error),
});
} else if (status >= 400) {
reqObs.log.warn("HTTP {status} {path}: {err}", {
status,
path,
err: error.message ?? String(error),
});
}
reqObs.log.error("HTTP error {path}: {err}", { path, err });
},
onResponse: (_response, event) => {
if (event.context.obs) {
event.context.obs.end();
}
onResponse: (response, event) => {
const reqObs = event.context.obs;
if (!reqObs) return;
const ms = Date.now() - ((event.context as any)._startMs ?? Date.now());
const status = response.status ?? 200;
const path = event.req.url ?? "unknown";
reqObs.log.info("{status} {path} {ms}ms", { status, path, ms });
reqObs.end();
},
});

View file

@ -175,37 +175,26 @@ export class Plugin extends BSBService<InstanceType<typeof Config>, typeof Event
});
reqObs.log.info("{method} {path}", { method, path });
event.context.obs = reqObs;
(event.context as any)._startMs = Date.now();
},
onError: (error, event) => {
const reqObs = event.context.obs;
const status = error.status ?? 500;
const path = event.req.url ?? "unknown";
const err = error.message ?? String(error);
if (!reqObs) {
obs.log.error("HTTP {status} {path}: {err} (no request trace)", {
status,
path,
err: error.message ?? String(error),
});
obs.log.error("HTTP error {path}: {err} (no request trace)", { path, err });
return;
}
if (status >= 500) {
reqObs.log.error("HTTP {status} {path}: {err}", {
status,
path,
err: error.message ?? String(error),
});
} else if (status >= 400) {
reqObs.log.warn("HTTP {status} {path}: {err}", {
status,
path,
err: error.message ?? String(error),
});
}
reqObs.log.error("HTTP error {path}: {err}", { path, err });
},
onResponse: (_response, event) => {
if (event.context.obs) {
event.context.obs.end();
}
onResponse: (response, event) => {
const reqObs = event.context.obs;
if (!reqObs) return;
const ms = Date.now() - ((event.context as any)._startMs ?? Date.now());
const status = response.status ?? 200;
const path = event.req.url ?? "unknown";
reqObs.log.info("{status} {path} {ms}ms", { status, path, ms });
reqObs.end();
},
});

View file

@ -80,9 +80,9 @@ export async function claimPairing(
obs?: Observable,
): Promise<PairingClaimResult> {
const pc = await repo.getPairingCode(code);
if (!pc) { obs?.log.debug("claim {code}: code not found", { code }); return { status: "pending" }; }
if (new Date(pc.expires_at) < new Date()) { obs?.log.debug("claim {code}: expired", { code }); return { status: "pending" }; }
if (!pc.consumed_at) { obs?.log.debug("claim {code}: not yet consumed", { code }); return { status: "pending" }; }
if (!pc) { obs?.log.info("claim {code}: code not found", { code }); return { status: "pending" }; }
if (new Date(pc.expires_at) < new Date()) { obs?.log.info("claim {code}: expired", { code }); return { status: "pending" }; }
if (!pc.consumed_at) { obs?.log.info("claim {code}: not yet consumed", { code }); return { status: "pending" }; }
const extras = pc.extras as Record<string, unknown>;
const kioskKey = extras["kiosk_key_plaintext"] as string | undefined;