@dotevolve/error-utils
v1.0.10
Published
Shared error handling utilities with Sentry integration for Node.js and Express services
Maintainers
Readme
@dotevolve/error-utils
Shared error handling utilities with Sentry integration for dot-cOS microservices.
Features
- 🎯 6-Category Error Classification: validation, authentication, authorization, conflict, not_found, system
- 🔍 Distributed Tracing: Sentry trace IDs for cross-service request tracking
- 🛡️ Data Sanitization: Automatic scrubbing of sensitive fields (passwords, tokens, etc.)
- 📊 Performance Monitoring: Sentry transaction tracking for database operations
- 🔄 Transaction Safety: Prisma transaction wrapper with automatic rollback
- 🎨 TypeScript Support: Full type definitions included
Installation
npm install @dotevolve/error-utils @sentry/node @sentry/profiling-nodeSubpath Exports
As of v1.0.7, the package is split into three environment-specific entry points to keep bundles lean and prevent peer dependency conflicts:
| Import path | Use case |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| @dotevolve/error-utils/node | Node.js services — initializeSentry, withTransaction, error classes |
| @dotevolve/error-utils/express | Express apps — all of the above + setupSentryMiddleware, correlationIdMiddleware, setupSentryErrorHandler, asyncHandler |
| @dotevolve/error-utils/react | React apps — initializeReactSentry, error classes |
| @dotevolve/error-utils | Root — all exports (convenience, same as /express) |
Quick Start
Node.js / Express API
1. Initialize Sentry in your server entry point
// server.js
const { initializeSentry } = require("@dotevolve/error-utils/node");
initializeSentry({
dsn: process.env.SENTRY_DSN,
serviceName: "my-service",
environment: process.env.NODE_ENV,
release: process.env.APP_VERSION,
});2. Setup Express Middleware
// app.js
const express = require("express");
const {
setupSentryMiddleware,
setupSentryErrorHandler,
correlationIdMiddleware,
} = require("@dotevolve/error-utils/express");
const app = express();
// 1. Sentry middleware (must be first)
setupSentryMiddleware(app);
// 2. Correlation ID middleware
app.use(correlationIdMiddleware);
// Your routes here
app.use("/api", routes);
// 3. Error handler (must be last)
setupSentryErrorHandler(app);3. Use Custom Error Classes
const {
ValidationError,
NotFoundError,
AuthorizationError,
asyncHandler,
} = require("@dotevolve/error-utils/express");
app.get(
"/users/:id",
asyncHandler(async (req, res) => {
const user = await User.findById(req.params.id);
if (!user) {
throw new NotFoundError("User", req.params.id);
}
if (!req.user.canViewUser(user)) {
throw new AuthorizationError("Cannot view this user");
}
res.json({ success: true, data: user });
}),
);4. Use Transaction Handler
const { withTransaction } = require("@dotevolve/error-utils/node");
async function createWorkflowWithSteps(data) {
return withTransaction(
prisma,
async (tx) => {
const workflow = await tx.workflow.create({ data: data.workflow });
const steps = await tx.workflowStep.createMany({
data: data.steps.map((s) => ({ ...s, workflowId: workflow.id })),
});
return { workflow, steps };
},
"create_workflow_with_steps",
);
}React App
Initialize Sentry in your app entry point
// src/lib/sentry.ts
import { initializeReactSentry } from "@dotevolve/error-utils/react";
initializeReactSentry({
dsn: import.meta.env.VITE_SENTRY_DSN,
environment: import.meta.env.MODE,
tracesSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
debug: import.meta.env.DEV,
});API Reference
Error Classes
Available from all three subpaths.
AppError
Base error class with Sentry integration.
new AppError(message: string, statusCode: number, category: string, details?: any)ValidationError (400)
new ValidationError(message: string, details?: Record<string, string[]>)AuthenticationError (401)
new AuthenticationError(message?: string)AuthorizationError (403)
new AuthorizationError(message?: string)NotFoundError (404)
new NotFoundError(resource: string, identifier?: string)ConflictError (409)
new ConflictError(message: string, details?: any)Middleware (/express)
setupSentryMiddleware(app)
Sets up Sentry request handler, tracing, and correlation ID middleware.
correlationIdMiddleware
Generates or preserves correlation IDs for request tracing.
setupSentryErrorHandler(app)
Sets up Sentry error handler and custom error response middleware.
attachSentryContext
Attaches user and request context to Sentry events.
asyncHandler(fn)
Wraps async route handlers to catch promise rejections.
Utilities (/node and /express)
withTransaction(prisma, callback, operationName)
Wraps Prisma transactions with Sentry performance monitoring.
sanitizeData(data, sensitiveFields?)
Sanitizes sensitive data by replacing values with '[REDACTED]'.
Sentry Configuration
initializeSentry(config) — /node and /express
interface SentryConfig {
dsn: string;
serviceName: string;
environment?: string;
release?: string;
tracesSampleRate?: number;
profilesSampleRate?: number;
sensitiveFields?: string[];
}initializeReactSentry(config) — /react
interface ReactSentryConfig {
dsn: string;
environment?: string;
tracesSampleRate?: number;
replaysSessionSampleRate?: number;
replaysOnErrorSampleRate?: number;
debug?: boolean;
}Error Response Format
All errors return a standardized JSON response:
{
"success": false,
"error": {
"code": "validation",
"category": "validation",
"message": "Invalid input data",
"correlationId": "abc123-def456-ghi789",
"details": {
"email": ["Email is required", "Email must be valid"]
}
},
"timestamp": "2024-01-15T10:30:00.000Z"
}Environment Variables
# Required
SENTRY_DSN=https://[key]@[org].ingest.sentry.io/[project]
# Optional
NODE_ENV=production
SENTRY_ENVIRONMENT=production
SENTRY_RELEASE=v1.0.7
SENTRY_TRACES_SAMPLE_RATE=0.1
SENTRY_PROFILES_SAMPLE_RATE=0.1
SENSITIVE_FIELDS=customField1,customField2Best Practices
- Always use
asyncHandlerfor async route handlers - Use specific error classes instead of generic
Error - Include validation details in
ValidationErrorfor field-level feedback - Use
withTransactionfor all multi-step database operations - Set correlation ID in inter-service HTTP calls
- Don't capture validation errors to Sentry (they're user errors, not system errors)
- Import from the correct subpath — use
/expressfor Express apps,/nodefor plain Node, and/reactfor React apps
Changelog
v1.0.7
- Fixed: Updated
exportsmap to useimport/requireconditions (wasdefault) — fixesTS2307in TypeScript projects usingmoduleResolution: bundler - Added: Root
.export as an alias for/expressfor backwards compatibility - Docs: Updated README to document subpath exports API
v1.0.6
- Added subpath exports:
./node,./express,./react - Added React Sentry integration via
initializeReactSentry
CI/CD
This package uses GitHub Actions for CI (testing) and CD (publishing).
Branching Strategy
master: Production-ready branch. Pushes to this branch trigger an NPM publish.dev: Development branch. All feature work should be merged here first.- Pull Requests: Pull requests should be raised from feature branches to
devor fromdevtomaster.
Workflows
- CI (ci.yml): Runs on pushes to
devand pull requests tomaster. It performsnpm testandnpm build. - Publish (publish.yml): Runs only on pushes to
master. It performsnpm test,npm build, andnpm publish.
Configuration
To enable automated publishing, you must configure a GitHub Environment:
- Go to your repository on GitHub.
- Navigate to Settings -> Environments.
- Click New environment and name it
production. - (Optional) Add Deployment protection rules like "Required reviewers" for manual approval.
- In the
productionenvironment, click Add secret. - Name:
NPM_TOKEN - Value: Your npm automation token.
[!NOTE] By using an environment, you can control which branches can deploy and require manual sign-off before publishing to NPM.
License
ISC
