A TypeScript library for generating stable, consistent error IDs based on error messages. This library is designed for error tracking and monitoring, allowing teams to identify and group similar errors consistently.
- Stable Error IDs: Same error message + category + metadata = Same ID
- Message Normalization: Automatically normalizes variable parts (IDs, timestamps, UUIDs)
- Metadata Filtering: Only includes relevant metadata keys for ID generation
- TypeScript Support: Full type safety with comprehensive interfaces
npm install stable-error
# or
yarn add stable-error
# or
bun add stable-errorimport { createStableError } from 'stable-error';
// Create a stable error
const error = createStableError('User not found', {
category: 'validation',
metadata: { userId: 123, field: 'email' }
});
console.log(error.id); // Always same for "User not found" + validation categoryStableError generates consistent 8-character hexadecimal IDs based on:
- Normalized message: Variable parts (numbers, UUIDs, timestamps) are replaced with placeholders
- Category: Error grouping category
- Filtered metadata: Only specific metadata keys are used for ID generation
The library automatically normalizes error messages by:
- Converting to lowercase and trimming whitespace
- Replacing numbers with
NUMBERplaceholder - Replacing UUIDs with
UUIDplaceholder - Replacing timestamps with
TIMESTAMPorTIMESTAMP_MSplaceholders - Normalizing multiple spaces to single space
// These all generate the same ID:
createStableError('User 123 not found', { category: 'test' });
createStableError('User 456 not found', { category: 'test' });
createStableError('USER 789 NOT FOUND', { category: 'test' });Only these metadata keys are used for stable ID generation:
typecodefieldoperationservicecomponent
// These generate the same ID (timestamp and userId are ignored):
createStableError('Error', {
metadata: { field: 'email', timestamp: '2023-01-01', userId: 123 }
});
createStableError('Error', {
metadata: { field: 'email', timestamp: '2023-12-31', userId: 456 }
});createStableError(messageOrError: string | Error, options?: StableErrorOptions): Error & ErrorJSONParameters:
messageOrError: The error message (string) or existing Error objectoptions: Optional configuration object
Options:
type StableErrorOptions = {
category?: string; // Default: 'general'
metadata?: Metadata; // Default: {}
statusCode?: number; // Default: 500
severity?: ErrorSeverity; // Default: 'medium'
};Returns: An Error object with additional properties for stable error tracking.
The returned error object extends the standard Error with these additional properties:
readonly id: string; // 8-character stable ID
readonly category: string; // Error category
readonly metadata: Metadata; // Error metadata
readonly statusCode: number; // HTTP status code
readonly severity: ErrorSeverity; // Error severity
readonly timestamp: string; // ISO timestampReturns JSON representation of the error:
const json = error.toJSON();
// {
// id: "a1b2c3d4",
// message: "User not found",
// category: "validation",
// metadata: { field: "email" },
// statusCode: 400,
// severity: "medium",
// timestamp: "2023-01-01T10:00:00Z",
// stack: "Error: User not found\n at ..."
// }import { createStableError } from 'stable-error';
// Create from string message
const error1 = createStableError('User not found', {
category: 'validation',
metadata: { field: 'email' }
});
// Create from existing Error
try {
// Some operation
} catch (err) {
const stableError = createStableError(err, {
category: 'database',
metadata: { operation: 'user_lookup' }
});
}import { createStableError } from 'stable-error';
// Create errors with consistent IDs
const error1 = createStableError('User 123 not found', {
category: 'validation',
metadata: { field: 'email' }
});
const error2 = createStableError('User 456 not found', {
category: 'validation',
metadata: { field: 'email' }
});
console.log(error1.id === error2.id); // true - same normalized message// Convert existing errors to stable errors
try {
await someAsyncOperation();
} catch (error) {
const stableError = createStableError(error, {
category: 'api',
severity: 'high',
metadata: {
endpoint: '/users',
method: 'GET'
}
});
// Log or track the stable error
console.log(`Error ID: ${stableError.id}`);
}type ErrorSeverity = 'low' | 'medium' | 'high' | 'critical';type Metadata = Record<string, unknown>;type ErrorJSON = {
id: string;
message: string;
category: string;
metadata: Metadata;
severity: ErrorSeverity;
timestamp: string;
statusCode: number;
stack?: string | undefined;
};- Modern browsers (ES2018+)
- Node.js 14+
- TypeScript 4.5+
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
MIT License - see LICENSE file for details.