npm package: @rivtor/errors
Description: Error dictionary with i18n support, Sentry integration, and actionable fixes
Author: Rivtor
Latest version: 1.1.0

# @rivtor/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

```bash
npm install @rivtor/errors
# or
yarn add @rivtor/errors
# or
pnpm add @rivtor/errors
```

## Quick Start

### 1. Create Error from Registry

```typescript
import { createError, RivtorAuthError } from '@rivtor/errors/server';

// Using error code
throw createError('INVALID_CREDENTIALS', {
  details: { email: 'user@example.com' }
});

// Using typed error class
throw RivtorAuthError.invalidCredentials();
throw RivtorAuthError.sessionExpired();
throw RivtorAuthError.missingPermission();
```

### 2. Get Localized Error Messages

```typescript
import { getErrorMessage, getErrorFix } from '@rivtor/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

```typescript
import { configureSentry, RivtorError } from '@rivtor/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 RivtorError('DATABASE_ERROR', {
  userId: 'user-123',
  context: { query: 'SELECT * FROM users' }
});
```

### 4. Format API Responses

```typescript
import { formatApiError } from '@rivtor/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.rivtor.com/errors/invalid-credentials'
//   }
// }
```

## API Reference

### Error Classes

```typescript
import {
  RivtorError,
  RivtorAuthError,
  RivtorValidationError,
  RivtorNotFoundError,
  RivtorRateLimitError,
  RivtorDatabaseError
} from '@rivtor/errors/server';

// Base error class
throw new RivtorError('CUSTOM_ERROR', {
  message: 'Something went wrong',
  details: { field: 'value' },
  fix: 'Try again later',
  docs: 'https://docs.example.com/error'
});

// Authentication errors
throw RivtorAuthError.invalidCredentials();
throw RivtorAuthError.sessionExpired();
throw RivtorAuthError.unauthorized();
throw RivtorAuthError.forbidden();
throw RivtorAuthError.missingPermission('read:users');

// Validation errors
throw RivtorValidationError.required('email');
throw RivtorValidationError.invalidFormat('email', 'user@example');
throw RivtorValidationError.outOfRange('age', 150, { min: 0, max: 120 });

// Not found errors
throw RivtorNotFoundError.user('user-123');
throw RivtorNotFoundError.resource('Post', 'post-456');

// Rate limit errors
throw RivtorRateLimitError.requestLimit(100, '1h');
throw RivtorRateLimitError.concurrentRequests(5);

// Database errors
throw RivtorDatabaseError.connectionFailed();
throw RivtorDatabaseError.queryFailed('SELECT * FROM users');
```

### Error Registry

```typescript
import {
  getErrorDefinition,
  getAllErrors,
  registerError
} from '@rivtor/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

```typescript
import {
  getErrorMessage,
  getErrorFix,
  getErrorDocs,
  getSupportedLanguages
} from '@rivtor/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.rivtor.com/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

```typescript
import {
  configureSentry,
  captureError,
  addBreadcrumb,
  setContext
} from '@rivtor/errors/server';

// Configure Sentry
configureSentry({
  dsn: 'https://examplePublicKey@o0.ingest.sentry.io/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: 'user@example.com' }
});

// Set context
setContext('payment', {
  amount: 100,
  currency: 'USD',
  provider: 'stripe'
});
```

### API Response Formatting

```typescript
import {
  formatApiError,
  formatSuccessResponse,
  withErrorHandling
} from '@rivtor/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

```typescript
import { configureErrors } from '@rivtor/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

1. **Use Type-Safe Errors**: Prefer typed error classes over raw codes
2. **Localize Everything**: Ensure all user-facing messages are localized
3. **Provide Actionable Fixes**: Every error should include a fix
4. **Log Context**: Always include relevant context when logging errors
5. **Document Errors**: Maintain documentation for all error codes

## License

MIT

---

Made with ❤️ by [Rivtor](https://rivtor.com)