欢迎页面支持多语言
This commit is contained in:
146
src/components/welcome/error-utils.ts
Normal file
146
src/components/welcome/error-utils.ts
Normal file
@@ -0,0 +1,146 @@
|
||||
import { extractAppCommandError, toErrorMessage } from "@/lib/app-error"
|
||||
|
||||
export type WelcomeErrorKey =
|
||||
| "errors.unknown"
|
||||
| "errors.invalidInput"
|
||||
| "errors.notFound"
|
||||
| "errors.alreadyExists"
|
||||
| "errors.dependencyMissing"
|
||||
| "errors.databaseError"
|
||||
| "errors.ioError"
|
||||
| "errors.externalCommandFailed"
|
||||
| "errors.windowOperationFailed"
|
||||
| "errors.gitNotInstalled"
|
||||
| "errors.targetDirectoryNotEmpty"
|
||||
| "errors.repositoryNotFound"
|
||||
| "errors.networkUnavailable"
|
||||
| "errors.authenticationFailed"
|
||||
| "errors.permissionDenied"
|
||||
|
||||
export interface WelcomeErrorResult {
|
||||
key: WelcomeErrorKey
|
||||
detail?: string
|
||||
}
|
||||
|
||||
export function normalizeErrorMessage(error: unknown): string {
|
||||
return toErrorMessage(error)
|
||||
}
|
||||
|
||||
function stripClonePrefix(message: string): string {
|
||||
return message.replace(/^clone failed:\s*/i, "").trim()
|
||||
}
|
||||
|
||||
function mapCommonCodeToKey(code: string): WelcomeErrorKey {
|
||||
switch (code) {
|
||||
case "invalid_input":
|
||||
return "errors.invalidInput"
|
||||
case "not_found":
|
||||
return "errors.notFound"
|
||||
case "already_exists":
|
||||
return "errors.alreadyExists"
|
||||
case "permission_denied":
|
||||
return "errors.permissionDenied"
|
||||
case "dependency_missing":
|
||||
return "errors.dependencyMissing"
|
||||
case "network_error":
|
||||
return "errors.networkUnavailable"
|
||||
case "authentication_failed":
|
||||
return "errors.authenticationFailed"
|
||||
case "database_error":
|
||||
return "errors.databaseError"
|
||||
case "io_error":
|
||||
return "errors.ioError"
|
||||
case "external_command_failed":
|
||||
return "errors.externalCommandFailed"
|
||||
case "window_operation_failed":
|
||||
return "errors.windowOperationFailed"
|
||||
default:
|
||||
return "errors.unknown"
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveWelcomeError(error: unknown): WelcomeErrorResult {
|
||||
const appError = extractAppCommandError(error)
|
||||
if (appError) {
|
||||
const key = mapCommonCodeToKey(appError.code)
|
||||
const detail =
|
||||
key === "errors.unknown" ? appError.detail || appError.message : undefined
|
||||
|
||||
return detail ? { key, detail } : { key }
|
||||
}
|
||||
|
||||
return {
|
||||
key: "errors.unknown",
|
||||
detail: normalizeErrorMessage(error),
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveCloneError(error: unknown): WelcomeErrorResult {
|
||||
const appError = extractAppCommandError(error)
|
||||
if (appError) {
|
||||
switch (appError.code) {
|
||||
case "dependency_missing":
|
||||
return { key: "errors.gitNotInstalled" }
|
||||
case "already_exists":
|
||||
return { key: "errors.targetDirectoryNotEmpty" }
|
||||
case "not_found":
|
||||
return { key: "errors.repositoryNotFound" }
|
||||
case "network_error":
|
||||
return { key: "errors.networkUnavailable" }
|
||||
case "authentication_failed":
|
||||
return { key: "errors.authenticationFailed" }
|
||||
case "permission_denied":
|
||||
return { key: "errors.permissionDenied" }
|
||||
default: {
|
||||
const key = mapCommonCodeToKey(appError.code)
|
||||
const detail =
|
||||
key === "errors.unknown"
|
||||
? appError.detail || appError.message
|
||||
: undefined
|
||||
return detail ? { key, detail } : { key }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const rawMessage = normalizeErrorMessage(error)
|
||||
const message = stripClonePrefix(rawMessage)
|
||||
const normalized = message.toLowerCase()
|
||||
|
||||
if (normalized.includes("git is not installed")) {
|
||||
return { key: "errors.gitNotInstalled" }
|
||||
}
|
||||
|
||||
if (normalized.includes("already exists and is not an empty directory")) {
|
||||
return { key: "errors.targetDirectoryNotEmpty" }
|
||||
}
|
||||
|
||||
if (normalized.includes("repository not found")) {
|
||||
return { key: "errors.repositoryNotFound" }
|
||||
}
|
||||
|
||||
if (
|
||||
normalized.includes("could not resolve host") ||
|
||||
normalized.includes("network is unreachable") ||
|
||||
normalized.includes("connection timed out") ||
|
||||
normalized.includes("failed to connect")
|
||||
) {
|
||||
return { key: "errors.networkUnavailable" }
|
||||
}
|
||||
|
||||
if (
|
||||
normalized.includes("authentication failed") ||
|
||||
normalized.includes("could not read username") ||
|
||||
normalized.includes("permission denied (publickey)")
|
||||
) {
|
||||
return { key: "errors.authenticationFailed" }
|
||||
}
|
||||
|
||||
if (normalized.includes("permission denied")) {
|
||||
return { key: "errors.permissionDenied" }
|
||||
}
|
||||
|
||||
return {
|
||||
key: "errors.unknown",
|
||||
detail: message || rawMessage || undefined,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user