@forgedock/fd-fastest-errors
v0.1.0
Published
Shared error types and utilities for FD-Fastest
Maintainers
Readme
@fd-fastest/errors
Comprehensive error handling system for the FD-Fastest toolkit with retry logic, circuit breakers, and error reporting.
Features
- ✅ Custom Error Classes - Structured errors with categorization
- ✅ Retry Logic - Exponential backoff with jitter
- ✅ Circuit Breaker - Prevent cascading failures
- ✅ Error Reporter - Collect and analyze errors
- ✅ TypeScript - Full type safety
- ✅ Lightweight - Zero dependencies (except Zod)
Installation
pnpm add @fd-fastest/errorsQuick Start
Basic Error Usage
import { NetworkError, ValidationError } from '@fd-fastest/errors';
// Throw specific error types
if (!url) {
throw new ValidationError('URL is required', 'url');
}
try {
const response = await fetch(url);
} catch (error) {
throw new NetworkError('Failed to fetch data', url, error);
}Retry Logic
import { retry, NetworkError } from '@fd-fastest/errors';
import { createLogger } from '@fd-fastest/logger';
const logger = createLogger({ name: 'retry-example' });
// Simple retry
const data = await retry(() => fetchData(url), {
maxAttempts: 3,
initialDelay: 1000,
backoffMultiplier: 2,
});
// With callbacks
const result = await retry(() => riskyOperation(), {
maxAttempts: 5,
onRetry: (error, attempt, delay) => {
logger.warn({ attempt, delay, err: error }, 'Retry scheduled');
},
});Circuit Breaker
import { CircuitBreaker } from '@fd-fastest/errors';
const breaker = new CircuitBreaker({
failureThreshold: 5, // Open after 5 failures
resetTimeout: 60000, // Try again after 60s
successThreshold: 2, // Close after 2 successes
onCircuitOpen: () => logger.warn('Circuit opened'),
onCircuitClose: () => logger.info('Circuit closed'),
});
// Use the circuit breaker
try {
const result = await breaker.execute(() => callExternalService());
} catch (error) {
if (error.code === 'CIRCUIT_BREAKER_OPEN') {
logger.warn('Service is currently unavailable');
}
}Error Reporting
import { globalErrorReporter } from '@fd-fastest/errors';
// Report errors
globalErrorReporter.report(error);
// Get statistics
const stats = globalErrorReporter.getStats();
logger.info('Error statistics', {
total: stats.total,
network: stats.byCategory.network,
});
// Export for analysis
const json = globalErrorReporter.exportJSON();
await writeFile('error-report.json', json);API Reference
Error Classes
All error classes extend FastestError:
NetworkError- Network connectivity issuesBrowserError- Browser automation failuresConfigValidationError- Configuration errorsValidationError- Data validation failuresTimeoutError- Operation timeoutsFileIOError- File system errorsAnalysisError- Analysis/parsing errorsSystemError- System-level errorsExternalServiceError- External API failures
FastestError Properties
class FastestError extends Error {
code: string; // Unique error code
category: ErrorCategory; // Error type
severity: ErrorSeverity; // low | medium | high | critical
recoverable: boolean; // Can retry?
context: ErrorContext; // Additional data
timestamp: Date; // When occurred
cause?: Error; // Original error
}RetryHandler Configuration
interface RetryConfig {
maxAttempts: number; // Max retry attempts
initialDelay: number; // First retry delay (ms)
maxDelay: number; // Max delay cap (ms)
backoffMultiplier: number; // Exponential multiplier
shouldRetry?: (error, attempt) => boolean;
onRetry?: (error, attempt, delay) => void;
}CircuitBreaker States
closed- Normal operationopen- Rejecting all requestshalf-open- Testing if service recovered
Best Practices
Use Specific Error Types
// ❌ Bad throw new Error('Network failed'); // ✅ Good throw new NetworkError('Failed to connect to API', apiUrl);Preserve Error Context
try { await operation(); } catch (error) { // Wrap and preserve original error throw new BrowserError('Page load failed', details, error); }Only Retry Recoverable Errors
const handler = new RetryHandler({ shouldRetry: (error) => { // Don't retry validation errors if (error instanceof ValidationError) { return false; } return error.recoverable; }, });Use Circuit Breakers for External Services
const apiBreaker = new CircuitBreaker({ failureThreshold: 3, resetTimeout: 30000, }); const data = await apiBreaker.execute(() => fetch(apiUrl));Monitor Error Patterns
// Periodically check error stats setInterval(() => { const stats = globalErrorReporter.getStats(); if (stats.byCategory.network > 10) { console.warn('High network error rate detected'); } }, 60000);
License
MIT
