Utils
Diagnostics

API

All exports come from @dev-bench/utils (re-exported from ./diagnostics/index.js). Every emitter writes a DiagnosticEvent to the configured hook (if any), then writes the canonical line to console.{warn,error,log}.

Emitters

ExportSignatureDedup'd?Console
warnNotImplemented(category: string, detail: string) => voidyes (not-impl:<category>)console.warn("⚠ NOT IMPLEMENTED ...")
warnDegraded(category: string, detail: string) => voidyes (degraded:<category>)console.warn("⚡ DEGRADED ...")
warnUnexpected(category: string, detail: string, data?: Record<string, unknown>) => voidnoconsole.error("🔴 UNEXPECTED ...")
logInfo(category: string, detail: string, data?: Record<string, unknown>) => voidnoconsole.log("ℹ INFO ...")
logError(category: string, err: unknown, detail?: string) => voidnoconsole.error("❌ ERROR ...")

logError serializes its err argument: Error instances are flattened to { name, message, stack } on event.data; anything else is passed through as { err }. When detail is omitted it falls back to err.message (or String(err) for non-Error throws), making .catch(logError) work as a one-liner.

tryCatchWarn

ExportSignatureSummary
tryCatchWarn<T>(category: string, fn: () => T | Promise<T>) => Promise<TryCatchResult<T>>Runs fn; routes any throw through logError(category, err) and returns the failure as data.
TryCatchResult<T>| { ok: true; value: T }
| { ok: false; error: unknown }
Discriminated union — callers MUST .exhaustive() over { ok }.

Always returns a Promise, even when fn is synchronous — keeps the type monomorphic and forces every call site to await.

Hook + reset

ExportSignatureSummary
setDiagnosticHook(fn: ((e: DiagnosticEvent) => void) | null) => voidInstall or clear the hook. The hook fires before the console.* line.
resetDiagnostics() => voidClears the dedup Set. Test-only — call from beforeEach.

Types

ExportShapeSummary
DiagnosticKind"not-implemented" | "degraded" | "unexpected" | "info" | "error"Discriminator on DiagnosticEvent.kind.
DiagnosticEvent{ kind: DiagnosticKind; category: string; detail: string; stack: string; data?: Record<string, unknown>; timestamp: number }What the hook receives. stack is a 3-frame mini-stack, not the full trace.
TryCatchResult<T>see aboveReturned by tryCatchWarn.

See the generated JSDoc reference for the full surface.

On this page