feat: add observability utilities and framework integration examples#24
Conversation
- Introduced `trpc-integration.ts` to demonstrate error handling integration with tRPC using error-x. - Implemented type-safe conversion utilities for ErrorX and TRPCError. - Created custom error formatter and middleware for tRPC. - Added client-side error handling and React Query integration for tRPC. - Introduced `zod-integration.ts` to showcase advanced Zod integration patterns with error-x. - Implemented validation utilities for Zod schemas, including safe parsing and aggregate error handling. - Added form validation helpers and API request validation examples.
…d logging, and OpenTelemetry integration
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #24 +/- ##
==========================================
Coverage 100.00% 100.00%
==========================================
Files 8 9 +1
Lines 1019 1160 +141
Branches 178 250 +72
==========================================
+ Hits 1019 1160 +141 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR adds an observability module for ErrorX, along with comprehensive framework integration examples and updated documentation/metadata to surface these capabilities.
Changes:
- Introduces
src/observability.tswith error fingerprinting, structured logging helpers, and OpenTelemetry span attribute utilities, and re‑exports them from the main index. - Adds a dedicated observability test suite plus example integrations for Express, Hono, tRPC, GraphQL, React, logging libraries, and Zod.
- Updates package metadata (
repository,bugs) and project documentation (README, LLMS, examples/README) to document and showcase the new observability features and integrations.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/observability.ts |
New observability utilities (fingerprints, structured log entries, OTel attributes, span helper) for ErrorX. |
src/index.ts |
Re-exports observability types and functions from the main public API surface. |
src/__tests__/observability.test.ts |
Adds unit tests covering fingerprint generation, log entry structure, OTel attributes, and recordError span helper behavior. |
package.json |
Corrects repository to object form and adds bugs field for improved npm metadata. |
examples/zod-integration.ts |
Demonstrates advanced Zod + ErrorX patterns (safe parse wrappers, aggregate validation, form helpers, API request validation, schema builder). |
examples/trpc-integration.ts |
Provides tRPC integration utilities (ErrorX↔TRPC conversion, formatter, middleware, client error parsing, React Query error handling). |
examples/react-error-boundary.tsx |
Implements a React error boundary, context hooks, and async helper integrated with ErrorX, plus example usage patterns. |
examples/logging-integration.ts |
Shows logging integration patterns for Pino/Winston and generic loggers, including deduplication helpers; one example Winston helper currently returns a config-shaped object. |
examples/hono-middleware.ts |
Adds Hono middleware and example app wiring using ErrorX; the error handler currently always returns status 400 at the type level instead of the actual error.httpStatus. |
examples/graphql-integration.ts |
Provides GraphQL (Apollo / graphql-yoga) integration: ErrorX-based formatting, plugins/maskers, GraphQLErrorX class, resolver wrappers, and client-side parsing. |
examples/express-middleware.ts |
Adds Express middleware utilities (error handler, async wrapper, request ID, 404 handler) and a full sample setup using ErrorX variants. |
examples/README.md |
Indexes all new example files and provides quick-start snippets for each integration. |
README.md |
Documents the observability module, adds API reference for new helpers, and summarizes integrations available under /examples. |
LLMS.md |
Updates LLM-facing quick-start and type reference docs to include observability helpers and their associated types. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Determine HTTP status | ||
| const status = error.httpStatus ?? 500 | ||
|
|
||
| // Build response | ||
| const response: ErrorResponse = { | ||
| error: { | ||
| code: error.code, | ||
| message: error.message, | ||
| timestamp: new Date(error.timestamp).toISOString(), | ||
| ...(requestId && { requestId }), | ||
| }, | ||
| } | ||
|
|
||
| // Include full error details in development | ||
| if (includeDetails) { | ||
| response.details = error.toJSON() | ||
| } | ||
|
|
||
| return c.json(response, status as 400) |
There was a problem hiding this comment.
The response status is always being cast to the literal type 400 here, which means TypeScript will treat this as always returning HTTP 400 even when error.httpStatus is something else (e.g., 500 or 404). This both misrepresents the actual error status in the type system and may encourage incorrect copy-paste usage; you should return status directly or cast it to Hono's StatusCode union (e.g., status as StatusCode) so the runtime and types both reflect the real HTTP status.
| /** | ||
| * Create a Winston logger with ErrorX support. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const logger = createWinstonLogger({ | ||
| * level: 'debug', | ||
| * serviceName: 'api-server' | ||
| * }) | ||
| * | ||
| * try { | ||
| * await operation() | ||
| * } catch (err) { | ||
| * logger.error('Operation failed', { | ||
| * error: ErrorX.from(err), | ||
| * context: { userId: '123' } | ||
| * }) | ||
| * } | ||
| * ``` | ||
| */ | ||
| export const createWinstonLogger = (options?: { | ||
| level?: string | ||
| serviceName?: string | ||
| prettyPrint?: boolean | ||
| }) => { | ||
| // Winston would be imported here, but we show the configuration pattern | ||
| const config = { | ||
| level: options?.level ?? 'info', | ||
| defaultMeta: { | ||
| service: options?.serviceName ?? 'app', | ||
| }, | ||
| format: { | ||
| combine: [ | ||
| { timestamp: true }, | ||
| errorXFormat(), | ||
| options?.prettyPrint | ||
| ? { prettyPrint: { colorize: true } } | ||
| : { json: true }, | ||
| ], | ||
| }, | ||
| transports: [ | ||
| { type: 'Console' }, | ||
| // Add file transport for production: | ||
| // { type: 'File', filename: 'logs/error.log', level: 'error' }, | ||
| // { type: 'File', filename: 'logs/combined.log' }, | ||
| ], | ||
| } | ||
|
|
||
| return config |
There was a problem hiding this comment.
The createWinstonLogger function currently returns a plain configuration-like object whose format and transports shapes do not match Winston's real API, but the JSDoc example shows const logger = createWinstonLogger(...) and then calling logger.error(...). This mismatch can confuse users copying the example; either import Winston and return an actual logger instance (e.g., winston.createLogger(config)) or adjust the docs and/or function name to clarify that this helper returns a config object, not a fully constructed logger.
Summary
Changes
Observability Module (
src/observability.ts)generateFingerprint()- Create unique error fingerprints for deduplicationtoLogEntry()- Convert errors to structured log entries (pino/winston compatible)toOtelAttributes()- Generate OpenTelemetry span attributesrecordError()- Helper for recording errors on OTel spansExamples
Package Metadata
repositoryto object formatbugsfield for GitHub issuesTest plan
🤖 Generated with Claude Code