/**
 * Platform Service Error System
 *
 * This module provides a comprehensive error handling system for the Platform Service,
 * with structured error types, error codes, and consistent patterns for logging and recovery.
 */
// Export error codes and types
export * from './error.codes.js';
// Export base error classes
export * from './base.errors.js';
// Export domain-specific error classes
export * from './reputation.errors.js';
// Export error handler
export * from './error-handler.js';
// Export utility function to create specific error types based on the error category
import { getErrorClassForCategory } from './base.errors.js';
export { getErrorClassForCategory };
// Import needed classes for utility functions
import { PlatformError } from './base.errors.js';
import { ErrorSeverity, ErrorCategory, ErrorRecoverability } from './error.codes.js';
/**
 * Create a typed error from a standard Error
 * Useful for converting errors from external libraries or APIs
 *
 * @param error Standard error to convert
 * @param code Error code to assign
 * @param contextData Additional context data
 * @returns Typed PlatformError
 */
export function fromError(error, code, contextData = {}) {
    return new PlatformError(error.message, code, ErrorSeverity.MEDIUM, ErrorCategory.OPERATION, ErrorRecoverability.NON_RECOVERABLE, {
        data: {
            ...contextData,
            originalError: {
                name: error.name,
                message: error.message,
                stack: error.stack
            }
        }
    });
}
/**
 * Determine if an error is retryable
 *
 * @param error Error to check
 * @returns Boolean indicating if the error should be retried
 */
export function isRetryable(error) {
    // If it's our platform error, use its recoverability property
    if (error && typeof error === 'object' && 'recoverability' in error) {
        return error.recoverability === ErrorRecoverability.RECOVERABLE ||
            error.recoverability === ErrorRecoverability.MAYBE_RECOVERABLE ||
            error.recoverability === ErrorRecoverability.TRANSIENT;
    }
    // Check if it's a network error (these are often transient)
    if (error && typeof error === 'object' && error.code) {
        const networkErrors = [
            'ECONNRESET', 'ECONNREFUSED', 'ETIMEDOUT', 'EHOSTUNREACH',
            'ENETUNREACH', 'ENOTFOUND', 'EPROTO', 'ECONNABORTED'
        ];
        return networkErrors.includes(error.code);
    }
    // By default, we can't determine if the error is retryable
    return false;
}
/**
 * Create a wrapped version of a function that catches errors
 * and converts them to typed PlatformErrors
 *
 * @param fn Function to wrap
 * @param errorCode Default error code to use
 * @param contextData Additional context data
 * @returns Wrapped function
 */
export function withErrorHandling(fn, errorCode, contextData = {}) {
    return (async function (...args) {
        try {
            return await fn(...args);
        }
        catch (error) {
            if (error && typeof error === 'object' && 'code' in error) {
                // Already a typed error, rethrow
                throw error;
            }
            throw fromError(error instanceof Error ? error : new Error(String(error)), errorCode, {
                ...contextData,
                fnName: fn.name,
                args: args.map(arg => typeof arg === 'object'
                    ? '[Object]'
                    : String(arg).substring(0, 100))
            });
        }
    });
}
/**
 * Retry a function with exponential backoff
 *
 * @param fn Function to retry
 * @param options Retry options
 * @returns Function result or throws after max retries
 */
export async function retry(fn, options = {}) {
    const { maxRetries = 3, initialDelay = 1000, maxDelay = 30000, backoffFactor = 2, retryableErrors = [] } = options;
    let lastError;
    for (let attempt = 0; attempt <= maxRetries; attempt++) {
        try {
            return await fn();
        }
        catch (error) {
            lastError = error instanceof Error
                ? error
                : new Error(String(error));
            // Check if we should retry
            const shouldRetry = attempt < maxRetries && (isRetryable(error) ||
                retryableErrors.some(pattern => {
                    if (typeof pattern === 'string') {
                        return lastError.message.includes(pattern);
                    }
                    return pattern.test(lastError.message);
                }));
            if (!shouldRetry) {
                throw lastError;
            }
            // Calculate delay with exponential backoff
            const delay = Math.min(initialDelay * Math.pow(backoffFactor, attempt), maxDelay);
            // Add jitter to prevent thundering herd problem (±20%)
            const jitter = 0.8 + Math.random() * 0.4;
            const actualDelay = Math.floor(delay * jitter);
            // Wait before next retry
            await new Promise(resolve => setTimeout(resolve, actualDelay));
        }
    }
    // This should never happen, but TypeScript needs it
    throw lastError;
}
//# sourceMappingURL=data:application/json;base64, 