"use strict";
/**
 * Custom error types for CCS CLI
 *
 * All custom errors extend CCSError which provides:
 * - Standardized exit codes
 * - Recoverable flag for retry logic
 * - Consistent error formatting
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.isRecoverableError = exports.isCCSError = exports.RetryableError = exports.ValidationError = exports.UserAbortError = exports.MigrationError = exports.ProxyError = exports.ProfileError = exports.ProviderError = exports.BinaryError = exports.AuthError = exports.NetworkError = exports.ConfigError = exports.CCSError = void 0;
const exit_codes_1 = require("./exit-codes");
/**
 * Base error class for all CCS errors
 * Extends standard Error with exit code and recovery information
 */
class CCSError extends Error {
    constructor(message, code = exit_codes_1.ExitCode.GENERAL_ERROR, recoverable = false) {
        super(message);
        this.code = code;
        this.recoverable = recoverable;
        this.name = 'CCSError';
        // Maintain proper stack trace in V8 environments
        if (Error.captureStackTrace) {
            Error.captureStackTrace(this, this.constructor);
        }
    }
}
exports.CCSError = CCSError;
/**
 * Configuration-related errors
 * Examples: missing config file, invalid JSON, corrupt settings
 */
class ConfigError extends CCSError {
    constructor(message, configPath) {
        super(message, exit_codes_1.ExitCode.CONFIG_ERROR, false);
        this.configPath = configPath;
        this.name = 'ConfigError';
    }
}
exports.ConfigError = ConfigError;
/**
 * Network-related errors
 * Examples: connection refused, timeout, DNS resolution failure
 */
class NetworkError extends CCSError {
    constructor(message, url, statusCode) {
        super(message, exit_codes_1.ExitCode.NETWORK_ERROR, true); // Network errors are typically recoverable
        this.url = url;
        this.statusCode = statusCode;
        this.name = 'NetworkError';
    }
}
exports.NetworkError = NetworkError;
/**
 * Authentication/authorization errors
 * Examples: invalid API key, expired token, insufficient permissions
 */
class AuthError extends CCSError {
    constructor(message, provider) {
        super(message, exit_codes_1.ExitCode.AUTH_ERROR, false);
        this.provider = provider;
        this.name = 'AuthError';
    }
}
exports.AuthError = AuthError;
/**
 * Binary/executable errors
 * Examples: Claude CLI not found, corrupted binary, permission denied
 */
class BinaryError extends CCSError {
    constructor(message, binaryPath) {
        super(message, exit_codes_1.ExitCode.BINARY_ERROR, false);
        this.binaryPath = binaryPath;
        this.name = 'BinaryError';
    }
}
exports.BinaryError = BinaryError;
/**
 * Provider-specific errors
 * Examples: API rate limit, service unavailable, invalid model
 */
class ProviderError extends CCSError {
    constructor(message, provider, details) {
        super(message, exit_codes_1.ExitCode.PROVIDER_ERROR, true); // Provider errors may be recoverable
        this.provider = provider;
        this.details = details;
        this.name = 'ProviderError';
    }
}
exports.ProviderError = ProviderError;
/**
 * Profile-related errors
 * Examples: profile not found, invalid profile name, duplicate profile
 */
class ProfileError extends CCSError {
    constructor(message, profileName, availableProfiles) {
        super(message, exit_codes_1.ExitCode.PROFILE_ERROR, false);
        this.profileName = profileName;
        this.availableProfiles = availableProfiles;
        this.name = 'ProfileError';
    }
}
exports.ProfileError = ProfileError;
/**
 * Proxy-related errors
 * Examples: proxy startup failure, port conflict, proxy timeout
 */
class ProxyError extends CCSError {
    constructor(message, port) {
        super(message, exit_codes_1.ExitCode.PROXY_ERROR, false);
        this.port = port;
        this.name = 'ProxyError';
    }
}
exports.ProxyError = ProxyError;
/**
 * Migration-related errors
 * Examples: failed to migrate config, backup creation failed
 */
class MigrationError extends CCSError {
    constructor(message, fromVersion, toVersion) {
        super(message, exit_codes_1.ExitCode.MIGRATION_ERROR, false);
        this.fromVersion = fromVersion;
        this.toVersion = toVersion;
        this.name = 'MigrationError';
    }
}
exports.MigrationError = MigrationError;
/**
 * User abort error (Ctrl+C, SIGINT)
 * Used when user explicitly cancels an operation
 */
class UserAbortError extends CCSError {
    constructor(message = 'Operation cancelled by user') {
        super(message, exit_codes_1.ExitCode.USER_ABORT, false);
        this.name = 'UserAbortError';
    }
}
exports.UserAbortError = UserAbortError;
/**
 * Input validation errors (model denylist, invalid format, length limits)
 * Distinguishes user-input validation failures from system errors
 */
class ValidationError extends CCSError {
    constructor(message, field) {
        super(message, exit_codes_1.ExitCode.GENERAL_ERROR, false);
        this.field = field;
        this.name = 'ValidationError';
    }
}
exports.ValidationError = ValidationError;
/**
 * Retryable/transient error
 * Signals that the operation may succeed on retry (e.g. rate limits, timeouts)
 */
class RetryableError extends CCSError {
    constructor(message, originalError, retryAfter // ms until next attempt
    ) {
        super(message, exit_codes_1.ExitCode.GENERAL_ERROR, true);
        this.originalError = originalError;
        this.retryAfter = retryAfter;
        this.name = 'RetryableError';
    }
}
exports.RetryableError = RetryableError;
/**
 * Type guard to check if an error is a CCSError
 */
function isCCSError(error) {
    return error instanceof CCSError;
}
exports.isCCSError = isCCSError;
/**
 * Type guard to check if an error is recoverable
 */
function isRecoverableError(error) {
    if (isCCSError(error)) {
        return error.recoverable;
    }
    return false;
}
exports.isRecoverableError = isRecoverableError;
//# sourceMappingURL=error-types.js.map