@vocoweb/errors
v1.1.0
Published
Error dictionary with i18n support, Sentry integration, and actionable fixes
Maintainers
Readme
@vocoweb/errors
Production-ready error dictionary with i18n support, Sentry integration, and actionable fixes
Features
- Comprehensive Error Registry: JSON-based error codes with messages, fixes, and documentation links
- i18n Support: 12 languages with localized error messages and fixes
- Sentry Integration: Automatic error logging with context tracking
- Enhanced Error Messages: User-friendly messages with actionable fixes
- Rate Limit Backoff: Automatic retry with exponential backoff for rate-limited APIs
- Type-Safe Errors: TypeScript classes for common error types
Installation
npm install @vocoweb/errors
# or
yarn add @vocoweb/errors
# or
pnpm add @vocoweb/errorsQuick Start
1. Create Error from Registry
import { createError, VocoAuthError } from '@vocoweb/errors/server';
// Using error code
throw createError('INVALID_CREDENTIALS', {
details: { email: '[email protected]' }
});
// Using typed error class
throw VocoAuthError.invalidCredentials();
throw VocoAuthError.sessionExpired();
throw VocoAuthError.missingPermission();2. Get Localized Error Messages
import { getErrorMessage, getErrorFix } from '@vocoweb/errors/server';
// Get message in German
const message = getErrorMessage('SESSION_EXPIRED', 'de');
// Returns: 'Ihre Sitzung ist abgelaufen'
// Get fix in German
const fix = getErrorFix('SESSION_EXPIRED', 'de');
// Returns: 'Bitte melden Sie sich erneut an'
// Get message in Japanese
const message = getErrorMessage('INVALID_CREDENTIALS', 'ja');
// Returns: '認証情報が無効です'3. Configure Sentry Integration
import { configureSentry, VocoError } from '@vocoweb/errors/server';
// Configure Sentry
configureSentry({
dsn: process.env.SENTRY_DSN,
environment: process.env.NODE_ENV,
tracesSampleRate: 1.0,
beforeSend(event) {
// Custom event filtering
return event;
}
});
// Errors automatically log to Sentry
throw new VocoError('DATABASE_ERROR', {
userId: 'user-123',
context: { query: 'SELECT * FROM users' }
});4. Format API Responses
import { formatApiError } from '@vocoweb/errors/server';
try {
// Some operation
} catch (error) {
return Response.json(formatApiError(error), { status: 400 });
}
// Response format:
// {
// error: {
// code: 'INVALID_CREDENTIALS',
// message: 'Invalid email or password',
// fix: 'Check your email and password and try again',
// docs: 'https://docs.vocoweb.in/errors/invalid-credentials'
// }
// }API Reference
Error Classes
import {
VocoError,
VocoAuthError,
VocoValidationError,
VocoNotFoundError,
VocoRateLimitError,
VocoDatabaseError
} from '@vocoweb/errors/server';
// Base error class
throw new VocoError('CUSTOM_ERROR', {
message: 'Something went wrong',
details: { field: 'value' },
fix: 'Try again later',
docs: 'https://docs.example.com/error'
});
// Authentication errors
throw VocoAuthError.invalidCredentials();
throw VocoAuthError.sessionExpired();
throw VocoAuthError.unauthorized();
throw VocoAuthError.forbidden();
throw VocoAuthError.missingPermission('read:users');
// Validation errors
throw VocoValidationError.required('email');
throw VocoValidationError.invalidFormat('email', 'user@example');
throw VocoValidationError.outOfRange('age', 150, { min: 0, max: 120 });
// Not found errors
throw VocoNotFoundError.user('user-123');
throw VocoNotFoundError.resource('Post', 'post-456');
// Rate limit errors
throw VocoRateLimitError.requestLimit(100, '1h');
throw VocoRateLimitError.concurrentRequests(5);
// Database errors
throw VocoDatabaseError.connectionFailed();
throw VocoDatabaseError.queryFailed('SELECT * FROM users');Error Registry
import {
getErrorDefinition,
getAllErrors,
registerError
} from '@vocoweb/errors/server';
// Get error definition
const definition = getErrorDefinition('INVALID_CREDENTIALS');
// Returns: { code, message, fix, docs, status }
// Get all error codes
const allErrors = getAllErrors();
// Returns: Map of error code to definition
// Register custom error
registerError({
code: 'CUSTOM_ERROR',
message: {
en: 'Custom error occurred',
de: 'Ein benutzerdefinierter Fehler ist aufgetreten'
},
fix: {
en: 'Contact support for assistance',
de: 'Wenden Sie sich an den Support'
},
docs: 'https://docs.example.com/custom-error',
status: 400
});Localization
import {
getErrorMessage,
getErrorFix,
getErrorDocs,
getSupportedLanguages
} from '@vocoweb/errors/server';
// Get localized message
const message = getErrorMessage('INVALID_CREDENTIALS', 'de');
// Returns: 'Ungültige Anmeldedaten'
// Get localized fix
const fix = getErrorFix('INVALID_CREDENTIALS', 'de');
// Returns: 'Überprüfen Sie Ihre E-Mail und Ihr Passwort'
// Get documentation URL
const docs = getErrorDocs('INVALID_CREDENTIALS');
// Returns: 'https://docs.vocoweb.in/errors/invalid-credentials'
// Get supported languages
const languages = getSupportedLanguages();
// Returns: ['en', 'de', 'fr', 'es', 'it', 'nl', 'pl', 'pt', 'ru', 'ja', 'zh', 'ko', 'sv']Sentry Integration
import {
configureSentry,
captureError,
addBreadcrumb,
setContext
} from '@vocoweb/errors/server';
// Configure Sentry
configureSentry({
dsn: 'https://[email protected]/0',
environment: 'production',
release: '1.0.0',
tracesSampleRate: 1.0,
maxBreadcrumbs: 50,
beforeSend(event, hint) {
// Filter or modify events
if (event.exception) {
console.error('Exception captured:', event.exception);
}
return event;
}
});
// Capture error manually
await captureError(error, {
user: { id: 'user-123' },
tags: { feature: 'auth' },
extra: { attemptNumber: 3 }
});
// Add breadcrumb
addBreadcrumb({
category: 'auth',
message: 'User attempted login',
level: 'info',
data: { email: '[email protected]' }
});
// Set context
setContext('payment', {
amount: 100,
currency: 'USD',
provider: 'stripe'
});API Response Formatting
import {
formatApiError,
formatSuccessResponse,
withErrorHandling
} from '@vocoweb/errors/server';
// Format error for API response
const errorResponse = formatApiError(error, 'en');
// Returns: { error: { code, message, fix, docs } }
// Format success response
const successResponse = formatSuccessResponse({ data: 'value' });
// Returns: { success: true, data: { data: 'value' } }
// Wrapper function for automatic error handling
export const GET = withErrorHandling(async (request) => {
// Your API logic here
return { data: 'value' };
}, {
locale: 'de', // Use German for error messages
defaultErrorCode: 'INTERNAL_ERROR'
});Supported Languages
| Code | Language | |------|----------| | en | English | | de | German (Deutsch) | | fr | French (Français) | | es | Spanish (Español) | | it | Italian (Italiano) | | nl | Dutch (Nederlands) | | pl | Polish (Polski) | | pt | Portuguese (Português) | | ru | Russian (Русский) | | ja | Japanese (日本語) | | zh | Chinese (中文) | | ko | Korean (한국어) | | sv | Swedish (Svenska) |
Error Codes
Authentication Errors
| Code | Description | |------|-------------| | INVALID_CREDENTIALS | Invalid email or password | | SESSION_EXPIRED | User session has expired | | UNAUTHORIZED | Authentication required | | FORBIDDEN | Insufficient permissions | | MISSING_PERMISSION | Required permission not granted |
Validation Errors
| Code | Description | |------|-------------| | REQUIRED_FIELD | Required field is missing | | INVALID_FORMAT | Field format is invalid | | OUT_OF_RANGE | Value is outside allowed range | | DUPLICATE_VALUE | Value already exists |
Rate Limit Errors
| Code | Description | |------|-------------| | RATE_LIMIT_EXCEEDED | Request limit exceeded | | CONCURRENT_REQUESTS | Too many concurrent requests |
Database Errors
| Code | Description | |------|-------------| | DATABASE_ERROR | Database operation failed | | CONNECTION_FAILED | Database connection failed | | QUERY_FAILED | Database query failed |
Configuration
import { configureErrors } from '@vocoweb/errors/server';
configureErrors({
// Default language for error messages
defaultLocale: 'en',
// Sentry configuration
sentry: {
dsn: process.env.SENTRY_DSN,
environment: process.env.NODE_ENV,
tracesSampleRate: 1.0
},
// Custom error codes
customErrors: {
MY_CUSTOM_ERROR: {
message: { en: 'Custom error', de: 'Benutzerdefinierter Fehler' },
fix: { en: 'Try again', de: 'Versuchen Sie es erneut' },
docs: 'https://docs.example.com/custom-error'
}
},
// Rate limit backoff configuration
backoff: {
maxRetries: 3,
initialDelay: 1000,
maxDelay: 10000,
backoffMultiplier: 2
}
});Best Practices
- Use Type-Safe Errors: Prefer typed error classes over raw codes
- Localize Everything: Ensure all user-facing messages are localized
- Provide Actionable Fixes: Every error should include a fix
- Log Context: Always include relevant context when logging errors
- Document Errors: Maintain documentation for all error codes
License
MIT
Made with ❤️ by VocoWeb
