Skip to content

feat(pino,evlog): allow customizing log level for procedure errors in pino and evlog plugins - #1949

Merged
dinwwwh merged 3 commits into
mainfrom
claude/orpc-error-logging-levels-55984e
Aug 26, 2026
Merged

feat(pino,evlog): allow customizing log level for procedure errors in pino and evlog plugins#1949
dinwwwh merged 3 commits into
mainfrom
claude/orpc-error-logging-levels-55984e

Conversation

@dinwwwh

@dinwwwh dinwwwh commented Aug 25, 2026

Copy link
Copy Markdown
Member

The pino and evlog handler plugins now log procedure errors at a level matching their intent instead of treating every failure the same, and both accept a new procedureErrorLevel option to customize that level per error. This lets expected business rejections stay out of error-level alerting while genuine failures keep full severity.

Resolves #1930

Behavior

  • Abort errors log as info, deliberately thrown ORPCErrors as warn, and everything unexpected as error — including ORPCError with the INTERNAL_SERVER_ERROR code, since oRPC itself throws it for failures like output validation.
  • procedureErrorLevel: (error, level) => Level receives the level applied by default and returns the level to use, so overriding one case is a single condition with return level as the fallback.
  • The option covers everywhere procedure errors are logged (handler interceptor, event-iterator and readable-stream outputs); internal handler failures always stay at error.

Docs

Both integration pages gained an "Error Logging Levels" section stating the defaults and showing a procedureErrorLevel example.

Testing

Existing suites extended: INTERNAL_SERVER_ERROR no longer downgraded, custom resolver receives (error, defaultLevel) and its return value is honored, returning the incoming level preserves default behavior. All package tests, repo-wide type checks, and lint pass.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 25, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
orpc dec6126 Commit Preview URL

Branch Preview URL
Aug 25 2026, 08:31 AM

@pkg-pr-new

pkg-pr-new Bot commented Aug 25, 2026

Copy link
Copy Markdown
More templates

@orpc/ai-sdk

npm i https://pkg.pr.new/@orpc/ai-sdk@1949

@orpc/arktype

npm i https://pkg.pr.new/@orpc/arktype@1949

@orpc/bun

npm i https://pkg.pr.new/@orpc/bun@1949

@orpc/client

npm i https://pkg.pr.new/@orpc/client@1949

@orpc/cloudflare

npm i https://pkg.pr.new/@orpc/cloudflare@1949

@orpc/contract

npm i https://pkg.pr.new/@orpc/contract@1949

@orpc/experimental-effect

npm i https://pkg.pr.new/@orpc/experimental-effect@1949

@orpc/evlog

npm i https://pkg.pr.new/@orpc/evlog@1949

@orpc/hibernation

npm i https://pkg.pr.new/@orpc/hibernation@1949

@orpc/json-schema

npm i https://pkg.pr.new/@orpc/json-schema@1949

@orpc/experimental-msw

npm i https://pkg.pr.new/@orpc/experimental-msw@1949

@orpc/nest

npm i https://pkg.pr.new/@orpc/nest@1949

@orpc/next

npm i https://pkg.pr.new/@orpc/next@1949

@orpc/node

npm i https://pkg.pr.new/@orpc/node@1949

@orpc/openapi

npm i https://pkg.pr.new/@orpc/openapi@1949

@orpc/opentelemetry

npm i https://pkg.pr.new/@orpc/opentelemetry@1949

@orpc/pinia-colada

npm i https://pkg.pr.new/@orpc/pinia-colada@1949

@orpc/pino

npm i https://pkg.pr.new/@orpc/pino@1949

@orpc/publisher

npm i https://pkg.pr.new/@orpc/publisher@1949

@orpc/ratelimit

npm i https://pkg.pr.new/@orpc/ratelimit@1949

@orpc/server

npm i https://pkg.pr.new/@orpc/server@1949

@orpc/shared

npm i https://pkg.pr.new/@orpc/shared@1949

@orpc/swr

npm i https://pkg.pr.new/@orpc/swr@1949

@orpc/tanstack-query

npm i https://pkg.pr.new/@orpc/tanstack-query@1949

@orpc/trpc

npm i https://pkg.pr.new/@orpc/trpc@1949

@orpc/valibot

npm i https://pkg.pr.new/@orpc/valibot@1949

@orpc/zod

npm i https://pkg.pr.new/@orpc/zod@1949

commit: dec6126

@codecov

codecov Bot commented Aug 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@codspeed-hq

codspeed-hq Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 30 untouched benchmarks


Comparing claude/orpc-error-logging-levels-55984e (dec6126) with main (2991776)

Open in CodSpeed

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ Minor suggestions inline — the change is clean and well-tested.

Reviewed changes

  • procedureErrorLevel option — new (error, level) => level option on both PinoHandlerPlugin and EvlogHandlerPlugin to customize the per-procedure error log level (resolves #1930).
  • Default level mapping — refactored the two near-identical error-logging helpers into a single logProcedureError + defaultErrorLevel per plugin; the deliberate behavior change is that ORPCError with INTERNAL_SERVER_ERROR now logs at error (previously warn).
  • Plugin wiring — option applied at all three sites per plugin (interceptor catch, async-iterator and readable-stream onError); internal handler failures stay at error.
  • Tests + docs — both suites extended with exact assertions (INTERNAL-SERVER stays error, custom fn receives (error, defaultLevel), returning the incoming level preserves the default); both integration pages gained an "Error Logging Levels" section.

The default mapping, the INTERNAL_SERVER_ERROR exception, the option plumbing at every logging site, and the interaction-safe behavior all check out. Tests use exact assertions rather than loose ones, so they can genuinely regress. Two small nits inline only.

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

Comment thread packages/evlog/src/handler-plugin.ts
Comment thread apps/content/docs/integrations/pino.mdx

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ No new issues from the added commit — tests are solid. The two minor notes from the initial review remain open.

Reviewed changes

  • logProcedureError early-return — evlog's helper now bails when no logger, so the custom procedureErrorLevel callback isn't invoked for calls with no logger in context. Matches pino's existing short-circuit (logger?.[key](...)) for consistent behavior.
  • No-logger test — pins that procedureErrorLevel is not called when the context has no logger.
  • createLoggerStorage adapter test — new packages/evlog/src/adapters/node.test.ts covers the AsyncLocalStorage-backed useLogger (returns the stored logger inside storage.run, throws the configured message outside).

The new tests use exact assertions and can genuinely fail. Production delta is limited to the early-return guard; both plugins now behave the same and skip the callback when there's no logger. No new findings.

Pullfrog  | Fix it ➔View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@dinwwwh dinwwwh changed the title feat: allow customizing log level for procedure errors in pino and evlog plugins feat(pino, evlog): allow customizing log level for procedure errors in pino and evlog plugins Aug 25, 2026
@dinwwwh dinwwwh changed the title feat(pino, evlog): allow customizing log level for procedure errors in pino and evlog plugins feat(pino,evlog): allow customizing log level for procedure errors in pino and evlog plugins Aug 25, 2026

@CamMcRae CamMcRae left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I like this API surface better than what is proposed in #1934. Just had some minor potential improvements

*
* @default (error, level) => level
*/
procedureErrorLevel?: (error: unknown, level: pino.Level) => pino.Level

@CamMcRae CamMcRae Aug 26, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we do something like this to allow for custom levels to be used?

export interface PinoHandlerPluginOptions<T extends Context, L extends string = never> {
  logger?: Logger<L>
  ...
  procedureErrorLevel?: (error: unknown, level: pino.Level) => pino.Level | L
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to create another github issue for this feature request, I need more votes

error: unknown,
procedureErrorLevel: Exclude<PinoHandlerPluginOptions<any>['procedureErrorLevel'], undefined>,
) {
logger?.[procedureErrorLevel(error, defaultProcedureErrorLevel(error))](error)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a level isn't found, this would end up throwing. This would help mitigate issues around that, but perhaps there is also an improvement to wrap this in try/catch that way a log can never be swallowed.

Suggested change
logger?.[procedureErrorLevel(error, defaultProcedureErrorLevel(error))](error)
logger?.[procedureErrorLevel(error, defaultProcedureErrorLevel(error))]?.(error)
Suggested change
logger?.[procedureErrorLevel(error, defaultProcedureErrorLevel(error))](error)
const defaultLevel = defaultProcedureErrorLevel(error);
try {
logger?.[procedureErrorLevel(error, defaultLevel)]?.(error)
} catch (e) {
// fallback to default level so the log can't be swallowed
logger?.[defaultLevel](error);
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are no typescript error, so it should be safe

@dinwwwh
dinwwwh merged commit 8b925be into main Aug 26, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add ability to change log level on error

2 participants