PushGo Auto Commit 2026-03-27T01:00:57.339Z

This commit is contained in:
2026-03-27 09:00:57 +08:00
commit eafa1ffd57
29 changed files with 3213 additions and 0 deletions

167
src/main/errors.ts Normal file
View File

@@ -0,0 +1,167 @@
import { AppErrorPayload, ErrorCode } from "../shared/contracts";
type ErrorDefinition = {
message: string;
actionText?: string;
actionType?: string;
};
const ERROR_MAP: Record<ErrorCode, ErrorDefinition> = {
APP_GIT_NOT_FOUND: {
message: "未检测到 Git请先安装后再继续",
actionText: "去安装 Git",
actionType: "open_git_download"
},
APP_GIT_HELPER_MISSING: {
message: "已安装 Git但未检测到可用凭据助手首次授权窗口可能无法弹出",
actionText: "安装凭据助手",
actionType: "open_gcm_download"
},
APP_GIT_HELPER_UNSUPPORTED: {
message: "当前 Git 凭据助手不支持授权弹窗,请切换到 Git Credential Manager",
actionText: "查看配置说明",
actionType: "open_gcm_download"
},
APP_FOLDER_INVALID: {
message: "请选择有效的项目文件夹"
},
URL_INVALID_FORMAT: {
message: "仓库地址格式不正确,请检查后重试"
},
URL_PLATFORM_MISMATCH: {
message: "仓库地址与当前平台不一致,是否切换平台?"
},
AUTH_CANCELLED: {
message: "你已取消登录授权,可重新发起"
},
AUTH_FAILED: {
message: "登录失败,请稍后重试"
},
GIT_INIT_FAILED: {
message: "初始化仓库失败,请检查文件夹权限"
},
GIT_COMMIT_NO_CHANGES: {
message: "没有检测到新变更,已尝试直接推送"
},
GIT_REMOTE_SET_FAILED: {
message: "设置远端仓库失败,请检查仓库地址"
},
GIT_PUSH_AUTH_FAILED: {
message: "推送失败:账号无权限或授权已失效"
},
GIT_PUSH_REJECTED: {
message: "推送被拒绝,远端可能有更新,请先同步"
},
NETWORK_TIMEOUT: {
message: "网络超时,请检查网络后重试"
},
UNKNOWN: {
message: "发生未知错误,请重试"
}
};
export class AppError extends Error {
readonly payload: AppErrorPayload;
constructor(code: ErrorCode, overrides?: Partial<AppErrorPayload>) {
const base = ERROR_MAP[code];
super(overrides?.message ?? base.message);
this.name = "AppError";
this.payload = {
code,
message: overrides?.message ?? base.message,
actionText: overrides?.actionText ?? base.actionText,
actionType: overrides?.actionType ?? base.actionType
};
}
}
export function createAppError(code: ErrorCode, overrides?: Partial<AppErrorPayload>): AppError {
return new AppError(code, overrides);
}
export function toAppErrorPayload(error: unknown, fallbackCode: ErrorCode = "UNKNOWN"): AppErrorPayload {
if (error instanceof AppError) {
return error.payload;
}
if (isPayload(error)) {
return error;
}
const base = ERROR_MAP[fallbackCode];
return {
code: fallbackCode,
message: base.message,
actionText: base.actionText,
actionType: base.actionType
};
}
function isPayload(error: unknown): error is AppErrorPayload {
return (
typeof error === "object" &&
error !== null &&
"code" in error &&
"message" in error &&
typeof (error as { code: unknown }).code === "string" &&
typeof (error as { message: unknown }).message === "string"
);
}
export function isGitNotFound(output: string): boolean {
const content = output.toLowerCase();
return content.includes("command not found") || content.includes("is not recognized") || content.includes("enoent");
}
export function inferGitPushError(stderr: string): AppError {
const message = stderr.toLowerCase();
if (message.includes("no credential store has been selected") || message.includes("credential.credentialstore")) {
return createAppError("GIT_PUSH_AUTH_FAILED", {
message: "Git Credential Manager 未配置凭据存储。请先配置 credential.credentialStore如 cache 或 secretservice后重试。"
});
}
if (message.includes("can not use the 'cache' credential store on windows")) {
return createAppError("GIT_PUSH_AUTH_FAILED", {
message: "Windows 不支持 cache 凭据存储。请改用 wincredman 后重试。"
});
}
if (message.includes("credential-manager") && message.includes("is not a git command")) {
return createAppError("GIT_PUSH_AUTH_FAILED", {
message: "未找到 Git Credential Manager 可执行程序,请安装并启用后重试。"
});
}
if (
message.includes("user interaction is not allowed") ||
message.includes("cannot prompt because user interactivity has been disabled") ||
message.includes("unable to open browser") ||
message.includes("failed to launch browser")
) {
return createAppError("GIT_PUSH_AUTH_FAILED", {
message: "无法拉起授权窗口。请检查系统默认浏览器与图形会话后重试。"
});
}
if (
message.includes("authentication failed") ||
message.includes("could not read username") ||
message.includes("403") ||
message.includes("access denied")
) {
return createAppError("GIT_PUSH_AUTH_FAILED");
}
if (message.includes("failed to push some refs") || message.includes("non-fast-forward") || message.includes("rejected")) {
return createAppError("GIT_PUSH_REJECTED");
}
if (message.includes("timed out") || message.includes("timeout")) {
return createAppError("NETWORK_TIMEOUT");
}
return createAppError("UNKNOWN");
}