1import * as Cause from "effect/Cause";
2import * as Effect from "effect/Effect";
3import * as ErrorReporter from "effect/ErrorReporter";
4
5/**
6 * Logs the defects of WebSocket RPC handlers. RpcServer reports every failed
7 * handler exit; typed failures are expected responses, so only dies are logged.
8 */
9const reporter: ErrorReporter.ErrorReporter = {
10 [ErrorReporter.TypeId]: ErrorReporter.TypeId,
11 report: ({ cause, fiber }) => {
12 for (const reason of cause.reasons) {
13 if (reason._tag !== "Die" || ErrorReporter.isIgnored(reason.defect)) continue;
14 // Reporters are called synchronously from the failing fiber. Logging with
15 // its context keeps its loggers and annotations, and a fork cannot throw
16 // back into the server that reported.
17 Effect.runForkWith(fiber.context)(
18 Effect.logError("Unhandled defect", Cause.fromReasons([reason])),
19 );
20 }
21 },
22};
23
24export const layer = ErrorReporter.layer([reporter]);