/** * @module @dotdo/postgres-shared/errors * * Standardized error handling for all postgres packages. * Provides a consistent error hierarchy with: * - Error codes for programmatic handling * - Original error cause preservation * - Context information for debugging * - Timestamp for timing information * - Serialization for Workers * - Recovery patterns (retryable, suggestions, circuit breaker categories) */ /** * Standard error codes for categorizing errors */ export type PostgresErrorCode = 'UNKNOWN' | 'INTERNAL' | 'NOT_IMPLEMENTED' | 'QUERY_ERROR' | 'QUERY_SYNTAX' | 'QUERY_TIMEOUT' | 'QUERY_CANCELLED' | 'TABLE_NOT_FOUND' | 'COLUMN_NOT_FOUND' | 'CONSTRAINT_VIOLATION' | 'UNIQUE_VIOLATION' | 'FOREIGN_KEY_VIOLATION' | 'NULL_VIOLATION' | 'CHECK_VIOLATION' | 'CONNECTION_ERROR' | 'CONNECTION_TIMEOUT' | 'CONNECTION_REFUSED' | 'CONNECTION_RESET' | 'CONNECTION_CLOSED' | 'NETWORK_ERROR' | 'DNS_ERROR' | 'VALIDATION_ERROR' | 'INVALID_PARAMETER' | 'INVALID_CONFIG' | 'INVALID_TYPE' | 'INVALID_FORMAT' | 'AUTH_ERROR' | 'AUTH_FAILED' | 'AUTH_EXPIRED' | 'AUTH_REQUIRED' | 'AUTH_FORBIDDEN' | 'PROTOCOL_ERROR' | 'PROTOCOL_VERSION' | 'MESSAGE_TOO_LARGE' | 'INVALID_MESSAGE' | 'INVALID_STATE' | 'CONFLICT' | 'CONCURRENCY_ERROR' | 'LOCK_ERROR' | 'NOT_FOUND' | 'ALREADY_EXISTS' | 'RATE_LIMITED' | 'QUOTA_EXCEEDED' | 'RESOURCE_EXHAUSTED'; /** * Context information for debugging errors */ export interface ErrorContext { /** SQL query that caused the error */ sql?: string; /** Query parameters */ params?: unknown[]; /** Table name involved */ table?: string; /** Column name involved */ column?: string; /** Schema name involved */ schema?: string; /** Constraint name involved */ constraint?: string; /** Database name */ database?: string; /** Connection URL (sanitized) */ connection?: string; /** Additional arbitrary context */ [key: string]: unknown; } /** Error category for circuit breaker decisions */ export type ErrorCategory = 'TRANSIENT' | 'PERMANENT' | 'UNKNOWN'; /** Retry configuration for calculateRetryDelay */ export interface RetryConfig { baseDelayMs: number; maxDelayMs: number; jitter?: boolean; } /** Metrics format for observability */ export interface ErrorMetrics { error_name: string; error_code: string; status_code: number; retryable: boolean; labels: { error_type: string; error_code: string; }; } /** Worker response format for safe serialization */ export interface WorkerErrorResponse { __errorType: string; code: PostgresErrorCode; message: string; statusCode: number; retryable: boolean; context: ErrorContext; } /** Standard JSON format for error serialization */ export interface StandardErrorJSON { name: string; code: string; message: string; statusCode: number; retryable: boolean; context: Record; timestamp: string; stack?: string; cause?: unknown; suggestion?: string; } /** * Base error class for all postgres-related errors. * * All custom errors in the postgres ecosystem should extend this class * to ensure consistent error handling patterns. * * @example * ```typescript * try { * await db.query('SELECT * FROM users') * } catch (error) { * if (error instanceof PostgresError) { * console.log('Error code:', error.code) * console.log('Context:', error.context) * console.log('Cause:', error.cause) * } * } * ``` */ export declare class PostgresError extends Error { /** Error code for programmatic handling */ readonly code: PostgresErrorCode; /** Context information for debugging */ readonly context: ErrorContext; /** HTTP status code equivalent (for API responses) */ readonly statusCode: number; /** Whether this error can be retried */ readonly retryable: boolean; /** Timestamp when the error was created */ readonly timestamp: Date; /** Recovery suggestion for this error */ readonly suggestion?: string; constructor(message: string, options?: { code?: PostgresErrorCode; cause?: Error | unknown; context?: ErrorContext; statusCode?: number; retryable?: boolean; suggestion?: string; }); /** * Convert to a plain object for JSON serialization */ toJSON(): StandardErrorJSON; /** * Create an error response object for API responses */ toResponse(): { error: true; code: PostgresErrorCode; message: string; details?: ErrorContext; }; /** * Create a serializable error format for Worker responses. * Includes a type discriminator for reconstruction. */ toWorkerResponse(): WorkerErrorResponse; /** * Get the root cause of the error chain. */ getRootCause(): Error; /** * Calculate retry delay with exponential backoff. * For RateLimitError, respects retryAfterMs if present. */ calculateRetryDelay(attempt: number, config: RetryConfig): number; /** * Get the circuit breaker category for this error. * - TRANSIENT: temporary failures (connection issues, timeouts) - retry may help * - PERMANENT: won't succeed on retry (validation, not found) * - UNKNOWN: unclear if retry will help */ getCircuitBreakerCategory(): ErrorCategory; /** * Convert error to metrics format for observability. */ toMetrics(): ErrorMetrics; /** * Reconstruct a PostgresError from JSON serialized data. * Used for deserializing errors that crossed Worker boundaries. */ static fromJSON(json: StandardErrorJSON): PostgresError; /** * Aggregate multiple errors into a single batch error. * Useful for batch operations that can have multiple failures. */ static aggregate(errors: PostgresError[], message: string): AggregatePostgresError; /** * Reconstruct a PostgresError from a Worker response. */ static fromWorkerResponse(response: WorkerErrorResponse): PostgresError; /** * Check if an object is a Worker error response. */ static isWorkerErrorResponse(obj: unknown): obj is WorkerErrorResponse; } /** * Error thrown when a query fails to execute */ export declare class QueryError extends PostgresError { constructor(message: string, options?: { code?: PostgresErrorCode; cause?: Error | unknown; context?: ErrorContext; sql?: string; params?: unknown[]; suggestion?: string; }); } /** * Error thrown when a query times out */ export declare class QueryTimeoutError extends QueryError { readonly timeoutMs: number; constructor(timeoutMs: number, options?: { cause?: Error | unknown; context?: ErrorContext; sql?: string; }); } /** * Error thrown for constraint violations */ export declare class ConstraintError extends QueryError { readonly constraintType: 'unique' | 'foreign_key' | 'null' | 'check' | 'unknown'; constructor(message: string, options?: { constraintType?: 'unique' | 'foreign_key' | 'null' | 'check' | 'unknown'; cause?: Error | unknown; context?: ErrorContext; sql?: string; constraint?: string; table?: string; column?: string; }); } /** * Error thrown for connection-related issues */ export declare class ConnectionError extends PostgresError { constructor(message: string, options?: { code?: PostgresErrorCode; cause?: Error | unknown; context?: ErrorContext; connection?: string; suggestion?: string; }); } /** * Error thrown when a connection times out */ export declare class ConnectionTimeoutError extends ConnectionError { readonly timeoutMs: number; constructor(timeoutMs: number, options?: { cause?: Error | unknown; context?: ErrorContext; connection?: string; }); } /** * Error thrown when validation fails */ export declare class ValidationError extends PostgresError { /** Fields that failed validation */ readonly fields: Record; constructor(message: string, options?: { code?: PostgresErrorCode; cause?: Error | unknown; context?: ErrorContext; fields?: Record; }); } /** * Error thrown for invalid configuration */ export declare class ConfigError extends ValidationError { constructor(message: string, options?: { cause?: Error | unknown; context?: ErrorContext; fields?: Record; }); } /** * Error thrown for authentication/authorization issues */ export declare class AuthenticationError extends PostgresError { constructor(message: string, options?: { code?: PostgresErrorCode; cause?: Error | unknown; context?: ErrorContext; }); } /** * Error thrown for protocol-level issues */ export declare class ProtocolError extends PostgresError { constructor(message: string, options?: { code?: PostgresErrorCode; cause?: Error | unknown; context?: ErrorContext; }); } /** * Error thrown when an operation is attempted in an invalid state */ export declare class StateError extends PostgresError { readonly currentState: string; readonly expectedStates: string[]; constructor(message: string, options: { currentState: string; expectedStates: string[]; cause?: Error | unknown; context?: ErrorContext; }); } /** * Error thrown when a concurrency conflict occurs */ export declare class ConflictError extends PostgresError { constructor(message: string, options?: { cause?: Error | unknown; context?: ErrorContext; expectedVersion?: number; actualVersion?: number; }); } /** * Error thrown when a resource is not found */ export declare class NotFoundError extends PostgresError { readonly resourceType: string; readonly resourceId: string; constructor(resourceType: string, resourceId: string, options?: { cause?: Error | unknown; context?: ErrorContext; }); } /** * Error thrown when a resource already exists */ export declare class AlreadyExistsError extends PostgresError { readonly resourceType: string; readonly resourceId: string; constructor(resourceType: string, resourceId: string, options?: { cause?: Error | unknown; context?: ErrorContext; }); } /** * Error thrown when rate limited */ export declare class RateLimitError extends PostgresError { readonly retryAfterMs: number; constructor(message: string, options?: { retryAfterMs?: number; cause?: Error | unknown; context?: ErrorContext; }); } /** * Error thrown for migration issues */ export declare class MigrationError extends PostgresError { readonly migrationId: string | undefined; readonly phase: string | undefined; constructor(message: string, options?: { migrationId?: string; phase?: string; cause?: Error | unknown; context?: ErrorContext; }); } /** * Check if an error is a PostgresError */ export declare function isPostgresError(error: unknown): error is PostgresError; /** * Check if an error has a specific error code */ export declare function hasErrorCode(error: unknown, code: PostgresErrorCode): boolean; /** * Check if an error is retryable */ export declare function isRetryableError(error: unknown): boolean; /** * Wrap an unknown error as a PostgresError. * Automatically sanitizes error messages to remove potential credentials. * Supports optional context merging when wrapping PostgresErrors. */ export declare function wrapError(error: unknown, defaultMessage?: string, options?: { context?: ErrorContext; }): PostgresError; /** * Create an error from an HTTP response */ export declare function fromHttpResponse(status: number, body: { message?: string; code?: string; details?: Record; }): PostgresError; /** * Error thrown for invalid SQL identifier names. * Used by identifier validation across packages. */ export declare class InvalidIdentifierError extends ValidationError { readonly identifier: string; readonly identifierType: 'table' | 'column' | 'schema' | string; readonly reason: string; constructor(name: string, type: 'table' | 'column' | 'schema' | string, reason: string); } /** * Error thrown when a circuit breaker is open and requests are rejected. */ export declare class CircuitOpenError extends PostgresError { readonly instanceId: string; readonly circuitState: string; readonly retryAfterMs: number; constructor(instanceId: string, state: string, retryAfterMs: number); } /** * Error thrown when a tenant cannot be identified from a request. */ export declare class TenantNotFoundError extends NotFoundError { constructor(message?: string); } /** * Error thrown when a tenant is blocked from accessing resources. */ export declare class TenantBlockedError extends AuthenticationError { readonly tenantId: string; constructor(tenantId: string, message?: string); } /** * Error thrown when a tenant ID format is invalid. */ export declare class InvalidTenantIdError extends ValidationError { readonly tenantId: string; constructor(tenantId: string, message?: string); } /** * Error thrown when a tenant DO request times out. */ export declare class TenantTimeoutError extends ConnectionTimeoutError { readonly tenantId: string; constructor(tenantId: string, timeoutMs: number, message?: string); } /** * Error thrown when a tenant DO is unreachable. */ export declare class TenantUnavailableError extends ConnectionError { readonly tenantId: string; constructor(tenantId: string, cause?: Error, message?: string); } /** * Error thrown when a tenant exceeds rate limits. */ export declare class TenantRateLimitError extends RateLimitError { readonly tenantId: string; constructor(tenantId: string, retryAfterSeconds: number, message?: string); } /** * Error thrown when a write operation is blocked in read-only mode. */ export declare class WriteBlockedError extends QueryError { /** PostgreSQL SQLSTATE code for read-only transaction */ readonly pgCode: string; constructor(sql: string); } /** * Error thrown when a snapshot is not found during recovery. */ export declare class SnapshotNotFoundError extends NotFoundError { constructor(snapshotId: string); } /** * Error thrown when recovery operation limits are exceeded. */ export declare class RecoveryLimitExceededError extends PostgresError { readonly limit: number; readonly actual: number; constructor(message: string, options: { limit: number; actual: number; context?: ErrorContext; }); } /** * Error thrown when recovery verification fails. */ export declare class RecoveryVerificationError extends PostgresError { constructor(message: string, options?: { cause?: Error; context?: ErrorContext; }); } /** * Error thrown when a timestamp is outside the valid range for time travel. */ export declare class TimestampOutOfRangeError extends ValidationError { readonly queryTimestamp: number; readonly minTimestamp: number; readonly maxTimestamp: number; constructor(timestamp: number, minTimestamp: number, maxTimestamp: number, message?: string); } /** * Error thrown when no snapshot is found for a time travel query. */ export declare class NoSnapshotFoundError extends NotFoundError { readonly queryTimestamp: number; constructor(timestamp: number, message?: string); } /** * Error thrown for invalid timestamp formats. */ export declare class InvalidTimestampError extends ValidationError { readonly value: unknown; constructor(value: unknown, message?: string); } /** * Error thrown for catalog operations (Iceberg, data lake). */ export declare class CatalogError extends PostgresError { constructor(message: string, options?: { code?: PostgresErrorCode; cause?: Error; context?: ErrorContext; statusCode?: number; retryable?: boolean; }); } /** * Error thrown when a commit conflict occurs in the catalog. */ export declare class CommitConflictError extends ConflictError { constructor(message: string, options?: { cause?: Error; context?: ErrorContext; expectedVersion?: number; actualVersion?: number; }); } /** * Error thrown when a table is not found in the catalog. */ export declare class CatalogTableNotFoundError extends NotFoundError { constructor(tableName: string, namespace?: string); } /** * Error thrown when a namespace is not found in the catalog. */ export declare class NamespaceNotFoundError extends NotFoundError { constructor(namespace: string); } /** * Error thrown for connection pool issues. */ export declare class PoolError extends ConnectionError { constructor(message: string, options?: { code?: PostgresErrorCode; cause?: Error; context?: ErrorContext; }); } /** * Error that aggregates multiple PostgresErrors. * Useful for batch operations that can have multiple failures. */ export declare class AggregatePostgresError extends PostgresError { /** The individual errors that were aggregated */ readonly errors: PostgresError[]; constructor(message: string, errors: PostgresError[]); toJSON(): StandardErrorJSON & { errors: StandardErrorJSON[]; }; } /** * Type guard to check if an error is a QueryError */ export declare function isQueryError(error: unknown): error is QueryError; /** * Type guard to check if an error is a ConnectionError */ export declare function isConnectionError(error: unknown): error is ConnectionError; /** * Type guard to check if an error is a ValidationError */ export declare function isValidationError(error: unknown): error is ValidationError; /** * Type guard to check if an error is an AuthenticationError */ export declare function isAuthenticationError(error: unknown): error is AuthenticationError; /** * Type guard to check if an error is a RateLimitError */ export declare function isRateLimitError(error: unknown): error is RateLimitError; /** * Type guard to check if an error is a NotFoundError */ export declare function isNotFoundError(error: unknown): error is NotFoundError; /** * Type guard to check if an error is a ConflictError */ export declare function isConflictError(error: unknown): error is ConflictError; /** * Narrow an error to a specific type based on its error code. * Returns the error with the narrowed type if the code matches. */ export declare function narrowByErrorCode(error: unknown, code: T): (PostgresError & { code: T; }) | undefined; //# sourceMappingURL=errors.d.ts.map