unerror
v1.0.1
Published
Unified error handling library for JavaScript and TypeScript
Maintainers
Readme
unerror
Unified error handling library providing consistent error management for JavaScript and TypeScript projects
Features
- 🎯 Type Safe - Full TypeScript type support
- 🔗 Error Chain Tracking - Track causal relationships between errors
- 📦 Serializable - Support for JSON serialization and deserialization
- 🎨 Formatted Output - Human-readable error descriptions
- 🔧 Simple API - Easy-to-use interface design
- 🌐 Cross-platform - Support for Node.js and browsers
- 📝 Complete Documentation - Detailed JSDoc documentation
Installation
npm install unerroryarn add unerrorpnpm add unerrorQuick Start
Basic Usage
import { UnError } from 'unerror';
// Create a simple error
const error = new UnError('User not found');
// With causal error
try {
// Some database operation
throw new Error('Connection timeout');
} catch (err) {
throw new UnError('Failed to fetch user', err);
}Error Chain
// Build error chain
const dbError = new Error('Connection failed');
const serviceError = new UnError('Database query failed', dbError);
const apiError = new UnError('API request failed', serviceError);
// Get complete error chain
const chain = apiError.getErrorChain();
console.log(`Error chain depth: ${chain.length}`); // 3
// Iterate through error chain
chain.forEach((err, index) => {
console.log(`[${index}] ${err.message}`);
});Serialization and Deserialization
// Serialize error
const error = new UnError('Operation failed');
const json = JSON.stringify(error.toJSON());
// Transfer over network or save to file...
// Deserialize
const data = JSON.parse(json);
const restored = UnError.fromJSON(data);
console.log(restored.message); // 'Operation failed'
console.log(restored.timestamp); // Original timestampFormatted Output
const error = new UnError('User not found');
// Basic formatting
console.log(error.format());
// Output:
// UnError: User not found
// Stack:
// at ...
// Custom format options
console.log(error.format({
includeStack: true,
includeCause: true,
indent: 4
}));
// Format entire error chain
const cause = new Error('Database error');
const error2 = new UnError('Query failed', cause);
console.log(error2.formatChain());
// Output:
// UnError: Query failed
// Stack:
// at ...
// ↳ Error: Database error
// Stack:
// at ...API Documentation
UnError Class
Constructor
new UnError(message?: string, cause?: Error | UnError, captureStackTrace?: boolean)Parameters:
message- Error message (optional)cause- Causal error for building error chains (optional)captureStackTrace- Whether to capture stack trace (default true)
Examples:
// Simple error
const error1 = new UnError('Something went wrong');
// With causal error
const error2 = new UnError('Operation failed', originalError);
// Disable stack capture
const error3 = new UnError('Error', undefined, false);Properties
message: string- Error messagename: string- Error name (default 'UnError')cause?: Error | UnError- Causal errortimestamp: number- Creation timestamp (milliseconds)stack?: string- Stack trace
Instance Methods
toJSON(): SerializedError
Serialize the error to a JSON-compatible object.
const serialized = error.toJSON();
const json = JSON.stringify(serialized);getErrorChain(): Array<Error | UnError>
Get the complete error chain from the current error to the root cause.
const chain = error.getErrorChain();
chain.forEach((err, index) => {
console.log(`${index}: ${err.message}`);
});format(options?: FormatOptions): string
Format the error as a human-readable string.
const formatted = error.format({
includeStack: true,
includeCause: true,
indent: 2
});
console.log(formatted);
// With stack cleaning
const cleanFormatted = error.format({
includeStack: true,
cleanStack: {
removeNodeInternals: true,
removeNodeModules: true
}
});
console.log(cleanFormatted);FormatOptions:
includeStack?: boolean- Whether to include stack trace (default true)includeCause?: boolean- Whether to include causal error (default true)indent?: number- Number of spaces for indentation (default 2)colors?: boolean- Whether to use colors (default false)cleanStack?: CleanStackOptions- Options for cleaning stack traces (optional)removeNodeInternals?: boolean- Remove Node.js internal modulesremoveNodeModules?: boolean- Remove node_modules framesremoveAnonymous?: boolean- Remove anonymous function frames
formatChain(options?: FormatOptions): string
Format the entire error chain as a string.
const formatted = error.formatChain({
includeStack: false,
indent: 2
});
console.log(formatted);
// With stack cleaning
const cleanFormatted = error.formatChain({
includeStack: true,
cleanStack: {
removeNodeInternals: true,
removeNodeModules: true,
removeAnonymous: false
}
});
console.log(cleanFormatted);withCause(cause: Error | UnError): UnError
Create a new error instance with the specified causal error.
const error = new UnError('Operation failed');
const wrapped = error.withCause(originalError);clone(): UnError
Clone the current error instance.
const error = new UnError('Test error');
const cloned = error.clone();parseStack(): StackFrame[]
Parse the stack trace into a structured array of stack frames.
const frames = error.parseStack();
frames.forEach(frame => {
console.log(`${frame.functionName} at ${frame.fileName}:${frame.lineNumber}`);
});StackFrame Interface:
interface StackFrame {
functionName?: string;
fileName?: string;
lineNumber?: number;
columnNumber?: number;
raw: string;
}print(options?: FormatOptions): this
Quickly print the error stack to console for debugging.
Note: UnError instances can also be printed directly via console.log(), console.error(), etc., which automatically call the toString() method to display error information.
// Basic usage
const error = new UnError('Operation failed', cause);
error.print();
// Custom options
error.print({ includeStack: false });
// Chaining
throw new UnError('Failed').print();
// Can also use console methods directly
console.error(error); // Automatically displays error infoStatic Methods
UnError.fromJSON(data: SerializedError): UnError
Create an error instance from serialized data.
const data = JSON.parse(json);
const error = UnError.fromJSON(data);UnError.isUnError(error: unknown): error is UnError
Type guard to check if a value is a UnError instance.
if (UnError.isUnError(error)) {
console.log('This is an UnError instance');
console.log(error.timestamp);
}Use Cases
1. API Error Handling
import { UnError } from 'unerror';
async function fetchUser(userId: string) {
try {
const response = await fetch(`/api/users/${userId}`);
if (!response.ok) {
throw new UnError(`Failed to fetch user: ${response.statusText}`);
}
return await response.json();
} catch (err) {
throw new UnError('User fetch operation failed', err as Error);
}
}
// Usage
try {
const user = await fetchUser('123');
} catch (err) {
if (UnError.isUnError(err)) {
console.error(err.formatChain());
}
}2. Distributed System Error Propagation
// Service A
const error = new UnError('Database query failed');
// Serialize and send over network
const json = JSON.stringify(error.toJSON());
await sendToServiceB(json);
// Service B
const data = JSON.parse(receivedJson);
const error = UnError.fromJSON(data);
// Add more context
throw new UnError('Service A operation failed', error);3. Logging
import { UnError } from 'unerror';
try {
// Some operation
throw new Error('Something went wrong');
} catch (err) {
const error = new UnError('Operation failed', err as Error);
// Log formatted error chain
logger.error(error.formatChain({
includeStack: true
}));
// Or log JSON format
logger.error(JSON.stringify(error.toJSON(), null, 2));
}4. Error Chain Analysis
function analyzeError(error: Error | UnError) {
if (!UnError.isUnError(error)) {
console.log('Standard error:', error.message);
return;
}
const chain = error.getErrorChain();
console.log(`Error chain depth: ${chain.length}`);
// Find specific type of error
const dbError = chain.find(err =>
err.message.includes('database') ||
err.message.includes('connection')
);
if (dbError) {
console.log('Found database error:', dbError.message);
}
// Parse stack
const frames = error.parseStack();
if (frames.length > 0) {
const topFrame = frames[0];
console.log(`Error occurred at: ${topFrame.fileName}:${topFrame.lineNumber}`);
}
}5. Quick Debugging
import { UnError } from 'unerror';
function processData(data: any) {
try {
// Some processing logic
if (!data.id) {
throw new UnError('Invalid data: missing id').print();
}
// More processing...
} catch (err) {
// Quickly print error chain for debugging
if (UnError.isUnError(err)) {
err.print({ includeStack: true });
}
throw err;
}
}
// Quick error viewing in development
const error = new UnError('Database connection failed', originalError);
error.print(); // Immediately print to console
// Also supports direct printing via console methods
console.log(error); // Automatically calls toString()
console.error(error); // Recommended for error output
console.dir(error); // View object structureTypeScript Support
unerror is written in TypeScript and provides complete type definitions:
import type {
UnError,
SerializedError,
FormatOptions,
StackFrame
} from 'unerror';
// Type-safe error handling
function handleError(error: unknown): void {
if (UnError.isUnError(error)) {
// TypeScript knows error is UnError type here
console.log(error.timestamp);
console.log(error.formatChain());
}
}Factory Functions
The library also provides factory functions for quick error creation (import from factory module):
import { createError, createErrorClass } from 'unerror';
// Quickly create error
const error = createError('Operation failed');
// Create custom error class
const DatabaseError = createErrorClass('DatabaseError');
const dbError = new DatabaseError('Connection failed');
console.log(dbError.name); // 'DatabaseError'Compatibility
- Node.js: >= 16.0.0
- TypeScript: >= 4.5.0
- Browsers: Modern browsers supporting ES2020
- Module Systems: ESM and CommonJS
Running Examples
The project includes multiple runnable examples demonstrating various use cases:
# Run all examples
npm run examples
# Run individual example
npm run example examples/01-basic-usage.ts
npm run example examples/02-error-chain.ts
npm run example examples/03-serialization.ts
npm run example examples/04-formatting.ts
npm run example examples/05-stack-parsing.ts
npm run example examples/06-real-world.ts
npm run example examples/07-custom-error-classes.ts
npm run example examples/08-print-method.tsExamples include:
- 01-basic-usage.ts - Basic usage
- 02-error-chain.ts - Error chain operations
- 03-serialization.ts - Serialization and deserialization
- 04-formatting.ts - Formatted output
- 05-stack-parsing.ts - Stack trace parsing
- 06-real-world.ts - Real-world scenarios
- 07-custom-error-classes.ts - Custom error classes
- 08-print-method.ts - Print error stack
See examples/README.md for more details.
License
MIT
Contributing
Contributions are welcome! Feel free to submit issues or pull requests.
