UNPKG

every-plugin

Version:
1 lines 15.3 kB
{"version":3,"file":"errors.mjs","names":[],"sources":["../../src/runtime/errors.ts"],"sourcesContent":["import { ORPCError } from \"@orpc/contract\";\nimport { Cause, Data } from \"effect\";\nimport type { z } from \"zod\";\n\nexport class PluginRuntimeError extends Data.TaggedError(\"PluginRuntimeError\")<{\n readonly pluginId?: string;\n readonly operation?: string;\n readonly procedureName?: string;\n readonly cause?: Error;\n readonly retryable: boolean;\n}> {}\n\nexport class ModuleFederationError extends Data.TaggedError(\"ModuleFederationError\")<{\n readonly pluginId: string;\n readonly remoteUrl: string;\n readonly cause?: Error;\n}> {}\n\nexport class ValidationError extends Data.TaggedError(\"ValidationError\")<{\n readonly pluginId: string;\n readonly stage: \"config\" | \"input\" | \"output\" | \"state\";\n readonly zodError: z.ZodError;\n}> {}\n\nconst extractErrorMessage = (error: unknown): string => {\n if (!error) return \"Unknown error\";\n\n if (error instanceof Error) {\n if (error.message) return error.message;\n if ((error as any).cause instanceof Error) {\n return extractErrorMessage((error as any).cause);\n }\n }\n\n if (error instanceof AggregateError && error.errors?.length) {\n return error.errors.map((e) => extractErrorMessage(e)).join(\"; \");\n }\n\n if (typeof error === \"object\" && \"message\" in error) {\n return String((error as any).message);\n }\n\n return String(error);\n};\n\nconst formatValidationIssue = (issue: any, index: number, maxDisplay: number): string => {\n if (index >= maxDisplay) return \"\";\n\n const path =\n Array.isArray(issue.path) && issue.path.length > 0\n ? issue.path.join(\".\")\n : issue.path || \"root\";\n\n const message = issue.message || \"Validation failed\";\n\n return `│ ${index + 1}. ${path}: ${message}`;\n};\n\nconst formatDataPreview = (data: unknown, maxLength = 100): string => {\n if (!data) return \"undefined\";\n\n try {\n const str = JSON.stringify(data);\n if (str.length <= maxLength) return str;\n\n if (typeof data === \"object\" && data !== null) {\n if (Array.isArray(data)) {\n return `Array(${data.length}) [...]`;\n }\n const keys = Object.keys(data);\n return `{ ${keys.slice(0, 3).join(\", \")}${keys.length > 3 ? \", ...\" : \"\"} }`;\n }\n\n return `${str.slice(0, maxLength)}...`;\n } catch {\n return String(data).slice(0, maxLength);\n }\n};\n\nconst formatORPCValidationError = (error: any): string[] | null => {\n const cause = error?.cause || error;\n\n if (!cause?.issues || !Array.isArray(cause.issues) || cause.issues.length === 0) {\n return null;\n }\n\n const lines: string[] = [];\n const errorType = error?.message || cause?.message || \"Validation failed\";\n\n lines.push(`\\n╭─ oRPC Validation Error ${\"\".repeat(30)}`);\n lines.push(`│ ${errorType}`);\n lines.push(`│`);\n\n const maxDisplay = 10;\n const totalIssues = cause.issues.length;\n\n lines.push(`│ Issues (${totalIssues}):`);\n\n const displayedIssues = cause.issues.slice(0, maxDisplay);\n displayedIssues.forEach((issue: any, idx: number) => {\n const formatted = formatValidationIssue(issue, idx, maxDisplay);\n if (formatted) lines.push(formatted);\n });\n\n if (totalIssues > maxDisplay) {\n lines.push(`│ ... and ${totalIssues - maxDisplay} more`);\n }\n\n if (cause.data !== undefined) {\n lines.push(`│`);\n lines.push(`│ Data preview: ${formatDataPreview(cause.data, 80)}`);\n }\n\n lines.push(`╰${\"\".repeat(50)}\\n`);\n\n return lines;\n};\n\nexport const formatORPCError = (error: any): void => {\n if (!(error instanceof ORPCError)) {\n return;\n }\n\n const validationLines = formatORPCValidationError(error);\n if (validationLines) {\n console.error(validationLines.join(\"\\n\"));\n return;\n }\n\n const lines: string[] = [];\n const code = error.code || \"UNKNOWN\";\n const status = error.status || 500;\n const message = error.message || \"An error occurred\";\n\n lines.push(`\\n╭─ oRPC Error ${\"\".repeat(40)}`);\n lines.push(`│ ${message}`);\n lines.push(`│ Code: ${code} (${status})`);\n lines.push(`│`);\n\n if (error.data) {\n const dataType = typeof error.data;\n if (dataType === \"object\" && error.data !== null) {\n if (\"retryAfter\" in error.data) {\n lines.push(`│ Retry after: ${error.data.retryAfter} seconds`);\n }\n if (\"remainingRequests\" in error.data) {\n lines.push(`│ Remaining: ${error.data.remainingRequests} requests`);\n }\n if (\"host\" in error.data) {\n lines.push(`│ Host: ${error.data.host}`);\n }\n if (\"port\" in error.data) {\n lines.push(`│ Port: ${error.data.port}`);\n }\n if (\"suggestion\" in error.data) {\n lines.push(`│ → ${error.data.suggestion}`);\n }\n if (\"resource\" in error.data) {\n lines.push(`│ Resource: ${error.data.resource}`);\n }\n if (\"resourceId\" in error.data) {\n lines.push(`│ ID: ${error.data.resourceId}`);\n }\n }\n }\n\n switch (code) {\n case \"UNAUTHORIZED\":\n lines.push(`│ → Check your API key or credentials`);\n break;\n case \"TOO_MANY_REQUESTS\":\n lines.push(`│ → Wait before retrying`);\n break;\n case \"SERVICE_UNAVAILABLE\":\n case \"BAD_GATEWAY\":\n case \"GATEWAY_TIMEOUT\":\n lines.push(`│ → The service may be temporarily unavailable`);\n break;\n case \"TIMEOUT\":\n lines.push(`│ → The operation took too long`);\n break;\n }\n\n lines.push(`╰${\"\".repeat(50)}\\n`);\n console.error(lines.join(\"\\n\"));\n};\n\nconst formatPluginError = (\n pluginId: string | undefined,\n operation: string | undefined,\n message: string,\n): void => {\n const lines: string[] = [];\n\n lines.push(`\\n╭─ Plugin Error ${\"\".repeat(40)}`);\n if (pluginId) lines.push(`│ Plugin: ${pluginId}`);\n if (operation) lines.push(`│ During: ${operation}`);\n lines.push(`│`);\n\n if (message.includes(\"ECONNREFUSED\")) {\n lines.push(`│ ❌ Connection refused`);\n lines.push(`│ `);\n lines.push(`│ A required service is not running.`);\n lines.push(`│ → Run: docker compose up -d`);\n } else if (message.includes(\"ENOTFOUND\")) {\n lines.push(`│ ❌ Host not found`);\n lines.push(`│ `);\n lines.push(`│ Check your connection URL or network settings.`);\n } else if (message.includes(\"ETIMEDOUT\") || message.includes(\"timeout\")) {\n lines.push(`│ ❌ Connection timeout`);\n lines.push(`│ `);\n lines.push(`│ The service took too long to respond.`);\n } else if (message.includes(\"EACCES\") || message.includes(\"permission\")) {\n lines.push(`│ ❌ Permission denied`);\n lines.push(`│ `);\n lines.push(`│ Check credentials or access permissions.`);\n } else if (message.includes(\"401\") || message.includes(\"unauthorized\")) {\n lines.push(`│ ❌ Authentication failed`);\n lines.push(`│ `);\n lines.push(`│ Check your API key or credentials.`);\n } else {\n lines.push(`│ ❌ ${message}`);\n }\n\n lines.push(`╰${\"\".repeat(50)}\\n`);\n\n console.error(lines.join(\"\\n\"));\n};\n\nconst isRetryableError = (message: string): boolean => {\n const retryablePatterns = [\"ETIMEDOUT\", \"ECONNRESET\", \"timeout\", \"503\", \"429\"];\n return retryablePatterns.some((p) => message.toLowerCase().includes(p.toLowerCase()));\n};\n\n// Helper to determine if an oRPC error code is retryable\nexport const isRetryableORPCCode = (code: string): boolean => {\n switch (code) {\n case \"TOO_MANY_REQUESTS\":\n case \"SERVICE_UNAVAILABLE\":\n case \"BAD_GATEWAY\":\n case \"GATEWAY_TIMEOUT\":\n case \"TIMEOUT\":\n return true;\n default:\n return false;\n }\n};\n\n// Convert ORPC errors from plugin procedures to PluginRuntimeError\nexport const wrapORPCError = (\n orpcError: ORPCError<string, unknown>,\n pluginId?: string,\n procedureName?: string,\n operation?: string,\n): PluginRuntimeError => {\n const validationLines = formatORPCValidationError(orpcError);\n if (validationLines) {\n console.error(validationLines.join(\"\\n\"));\n }\n\n return new PluginRuntimeError({\n pluginId,\n operation,\n procedureName,\n retryable: isRetryableORPCCode(orpcError.code),\n cause: orpcError as Error,\n });\n};\n\n/**\n * Extracts the underlying error from Effect's FiberFailure wrapper.\n * When Effect.runPromise rejects, errors are wrapped in FiberFailure.\n * This extracts the original error so oRPC can handle it properly.\n */\nexport const extractFromFiberFailure = (error: unknown): unknown => {\n if (!error || typeof error !== \"object\") return error;\n\n if (\"cause\" in error) {\n const cause = (error as { cause?: unknown }).cause;\n\n if (cause && typeof cause === \"object\" && \"_tag\" in cause) {\n try {\n const squashed = Cause.squash(cause as Cause.Cause<unknown>);\n if (squashed instanceof ORPCError) {\n return squashed;\n }\n return squashed;\n } catch {\n // Not a valid Cause\n }\n }\n\n if (cause instanceof ORPCError) {\n return cause;\n }\n }\n\n return error;\n};\n\n// Universal error converter for the runtime\nexport const toPluginRuntimeError = (\n error: unknown,\n pluginId?: string,\n procedureName?: string,\n operation?: string,\n defaultRetryable = false,\n): PluginRuntimeError => {\n if (error instanceof ORPCError) {\n return wrapORPCError(error, pluginId, procedureName, operation);\n }\n\n if (error instanceof PluginRuntimeError) {\n return error;\n }\n\n const validationLines = formatORPCValidationError(error);\n if (validationLines) {\n console.error(validationLines.join(\"\\n\"));\n } else {\n const message = extractErrorMessage(error);\n formatPluginError(pluginId, operation, message);\n }\n\n return new PluginRuntimeError({\n pluginId,\n operation,\n procedureName,\n retryable: defaultRetryable || isRetryableError(extractErrorMessage(error)),\n cause: error instanceof Error ? error : new Error(extractErrorMessage(error)),\n });\n};\n"],"mappings":"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"}