API Reference
Complete TypeScript API documentation for Structured Error Handler.
Class: StructuredError
Main error class that extends the standard Error with context preservation.
class StructuredError extends Error {
readonly code?: string;
readonly category?: string;
readonly context: ErrorContext[];
readonly cause?: Error;
}Constructor
new StructuredError(message: string, options?: StructuredErrorOptions)Parameters:
message- Human-readable error messageoptions- Optional configuration (see StructuredErrorOptions)
Example:
const error = new StructuredError('File not found', {
code: 'ENOENT',
category: 'io',
operation: 'readFile',
component: 'FileSystem',
metadata: { path: '/etc/config.json' }
});Static Methods
StructuredError.wrap
Wrap an existing error with additional context.
static wrap(
error: unknown,
message: string,
options?: StructuredErrorOptions
): StructuredErrorParameters:
error- Original error (Error, string, or unknown)message- New error messageoptions- Optional configuration
Returns: New StructuredError with cause set to original
Behavior:
- If
erroris a StructuredError, inheritscodeandcategory(unless overridden) - If
erroris a string, converts to Error first - Copies context chain from original StructuredError
Example:
try {
await fetch(url);
} catch (err) {
throw StructuredError.wrap(err, 'API request failed', {
code: 'API_ERROR',
operation: 'fetchData'
});
}StructuredError.from
Convert any value to a StructuredError.
static from(
error: unknown,
options?: Omit<StructuredErrorOptions, 'cause'>
): StructuredErrorParameters:
error- Any value (Error, StructuredError, string, unknown)options- Optional context to add
Returns: StructuredError
Behavior:
- If already a StructuredError, adds context and returns clone
- If Error, wraps with the same message
- If string, creates new StructuredError with that message
- If other, creates with
String(error)as message
Example:
function handleError(err: unknown): StructuredError {
return StructuredError.from(err, {
operation: 'handleError',
component: 'ErrorHandler'
});
}StructuredError.fromJSON
Deserialize a StructuredError from JSON.
static fromJSON(json: SerializedError): StructuredErrorParameters:
json- Serialized error object
Returns: Reconstituted StructuredError
Example:
const json = JSON.parse(errorString);
const error = StructuredError.fromJSON(json);
console.log(error instanceof StructuredError); // trueInstance Methods
addContext
Add context information to the error (returns new instance).
addContext(
operation: string,
options?: {
component?: string;
metadata?: Record<string, unknown>;
}
): StructuredErrorParameters:
operation- Name of the operation being performedoptions.component- Optional component or module nameoptions.metadata- Optional additional metadata
Returns: New StructuredError with context prepended (immutable pattern)
Example:
const enriched = error.addContext('processRequest', {
component: 'RequestHandler',
metadata: { requestId: 'abc123' }
});toJSON
Serialize error to JSON-compatible object.
toJSON(): SerializedErrorReturns: SerializedError object
Note: Automatically called by JSON.stringify()
Example:
const serialized = error.toJSON();
const jsonString = JSON.stringify(error); // Uses toJSON()toString
Format error as human-readable string.
toString(): stringReturns: Formatted string with code, message, context, and cause chain
Example Output:
[DB_ERROR] Database connection failed
Context:
→ handleRequest (Controller) {"endpoint":"/api"}
→ queryUser (Repository) {"userId":"123"}
Caused by:
Connection refusedhasCode
Check if error or any cause has the specified code.
hasCode(code: string): booleanParameters:
code- Error code to search for
Returns: true if code found in error or any cause
Example:
if (error.hasCode('ENOENT')) {
console.log('File not found');
}hasCategory
Check if error or any cause has the specified category.
hasCategory(category: string): booleanParameters:
category- Category to search for
Returns: true if category found in error or any cause
Example:
if (error.hasCategory('validation')) {
return res.status(400).json({ error: error.message });
}getRootCause
Get the deepest error in the cause chain.
getRootCause(): ErrorReturns: The original/root error
Example:
const root = error.getRootCause();
console.log('Original error:', root.message);getCauseChain
Get all errors in the cause chain as an array.
getCauseChain(): Error[]Returns: Array of errors, starting with current error
Example:
const chain = error.getCauseChain();
console.log('Chain depth:', chain.length);
chain.forEach((err, i) => {
console.log(`[${i}] ${err.message}`);
});Types
ErrorContext
Context information attached to an error.
interface ErrorContext {
/** The operation that was being performed */
operation: string;
/** Optional component or module name */
component?: string;
/** Additional metadata (must be JSON-serializable) */
metadata?: Record<string, unknown>;
/** ISO 8601 timestamp when context was added */
timestamp: string;
}SerializedError
JSON-serializable representation of an error.
interface SerializedError {
/** Error name/type (e.g., "StructuredError", "TypeError") */
name: string;
/** Human-readable error message */
message: string;
/** Error code for programmatic handling */
code?: string;
/** Error category for grouping */
category?: string;
/** Stack trace */
stack?: string;
/** Context chain, most recent first */
context: ErrorContext[];
/** Serialized cause error */
cause?: SerializedError;
}StructuredErrorOptions
Options for creating a StructuredError.
interface StructuredErrorOptions {
/** Error code for programmatic handling */
code?: string;
/** Error category for grouping */
category?: string;
/** The operation being performed */
operation?: string;
/** Component or module name */
component?: string;
/** Additional metadata (must be JSON-serializable) */
metadata?: Record<string, unknown>;
/** The underlying cause */
cause?: Error;
}Helper Functions
serializeError
Serialize any error to JSON format.
function serializeError(error: Error): SerializedErrorParameters:
error- Any Error (including StructuredError)
Returns: SerializedError
Behavior:
- Works with StructuredError (uses toJSON)
- Works with plain Error (extracts name, message, stack)
- Recursively serializes cause chain
Example:
const plainError = new TypeError('Invalid argument');
const serialized = serializeError(plainError);
console.log(serialized.name); // 'TypeError'deserializeError
Deserialize a SerializedError back to Error.
function deserializeError(serialized: SerializedError): ErrorParameters:
serialized- SerializedError object
Returns: StructuredError if name is "StructuredError", otherwise Error
Example:
const json = { name: 'Error', message: 'Test', context: [] };
const error = deserializeError(json);
console.log(error.message); // 'Test'formatError
Format any error for human-readable display.
function formatError(
error: Error,
options?: { includeStack?: boolean }
): stringParameters:
error- Any Error (StructuredError uses its toString)options.includeStack- Include stack trace (default: false)
Returns: Formatted string
Example:
console.log(formatError(error)); // Basic format
console.log(formatError(error, { includeStack: true })); // With stackComplete Example
import {
StructuredError,
serializeError,
deserializeError,
formatError,
type ErrorContext,
type SerializedError,
type StructuredErrorOptions
} from './index.js';
// Create structured error
const error = new StructuredError('Operation failed', {
code: 'OP_FAILED',
category: 'business',
operation: 'processOrder',
component: 'OrderService',
metadata: { orderId: '12345' }
});
// Add context
const enriched = error.addContext('handleRequest', {
component: 'OrderController',
metadata: { requestId: 'req-abc' }
});
// Check properties
if (enriched.hasCode('OP_FAILED')) {
console.log('Order processing failed');
}
// Serialize for logging
const serialized: SerializedError = enriched.toJSON();
console.log(JSON.stringify(serialized));
// Deserialize
const restored = StructuredError.fromJSON(serialized);
console.log(restored.toString());
// Format for display
console.log(formatError(restored, { includeStack: true }));
// Root cause analysis
const chain = restored.getCauseChain();
const root = restored.getRootCause();
console.log(`Chain depth: ${chain.length}, Root: ${root.message}`);Context Chain Order
Context is stored most recent first (stack order):
context[0] = handleRequest (most recent, top of stack)
context[1] = processOrder (earlier)
context[2] = queryDatabase (original operation)This matches natural debugging order: start from where the error surfaced and trace back.
Serialization Format
JSON output structure:
{
"name": "StructuredError",
"message": "Database query failed",
"code": "DB_ERROR",
"category": "database",
"stack": "StructuredError: Database query failed\n at ...",
"context": [
{
"operation": "handleRequest",
"component": "Controller",
"metadata": { "endpoint": "/api/users" },
"timestamp": "2025-12-26T12:00:00.000Z"
},
{
"operation": "findUser",
"component": "Repository",
"metadata": { "userId": "123" },
"timestamp": "2025-12-26T11:59:59.500Z"
}
],
"cause": {
"name": "Error",
"message": "Connection refused",
"stack": "...",
"context": []
}
}Error Properties
| Property | Type | Description |
|---|---|---|
name | string | Always "StructuredError" |
message | string | Human-readable error message |
code | string? | Programmatic error code |
category | string? | Error category for grouping |
context | ErrorContext[] | Context chain (most recent first) |
cause | Error? | Underlying error |
stack | string? | Stack trace |
Exit Codes (CLI)
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Error (invalid input, parse failure, unknown command) |
See Also
- Library Usage - Integration patterns
- Examples - Code examples
- CLI Usage - Command-line interface
- SPEC.md - Technical specification