feat(desktop-client): expand publisher error normalization
新增登录态失效与微信公众号外链缺失两类发布错误归一化, 将原本散落在适配器里的中文提示集中到 shared/publisher-errors, 让渲染层与 main 进程共用同一份用户可读文案。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,10 @@ import {
|
||||
sessionFetchText,
|
||||
uploadHtmlImages,
|
||||
} from "./common";
|
||||
import {
|
||||
WEIXIN_GZH_PUBLIC_URL_MISSING_MESSAGE,
|
||||
normalizeWeixinGzhPublishErrorMessage,
|
||||
} from "../../shared/publisher-errors";
|
||||
import {
|
||||
fetchImageAssetBlob,
|
||||
getCenteredCropRect,
|
||||
@@ -1932,10 +1936,10 @@ function failureResult(error: unknown): ReturnType<PublishAdapter["publish"]> ex
|
||||
if (message.startsWith("weixin_gzh_public_url_missing")) {
|
||||
return {
|
||||
status: "failed",
|
||||
summary: "微信公众号已提交发布,但未能获取外部文章链接,请在公众号后台发表记录确认。",
|
||||
summary: WEIXIN_GZH_PUBLIC_URL_MISSING_MESSAGE,
|
||||
error: {
|
||||
code: "weixin_gzh_public_url_missing",
|
||||
message,
|
||||
message: normalizeWeixinGzhPublishErrorMessage(message) ?? WEIXIN_GZH_PUBLIC_URL_MISSING_MESSAGE,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
PUBLISH_ACCOUNT_NOT_LOGGED_IN_MESSAGE,
|
||||
QIEHAO_REAL_NAME_AUTH_MESSAGE,
|
||||
WANGYIHAO_DRAFT_SAVE_PARAMETER_MESSAGE,
|
||||
WANGYIHAO_PUBLISH_CLICK_MESSAGE,
|
||||
WANGYIHAO_TOKEN_MISSING_MESSAGE,
|
||||
WEIXIN_GZH_PUBLIC_URL_MISSING_MESSAGE,
|
||||
isQiehaoRealNameAuthError,
|
||||
normalizePublisherErrorMessage,
|
||||
normalizePublisherLoginErrorMessage,
|
||||
normalizeQiehaoPublishErrorMessage,
|
||||
normalizeWangyihaoPublishErrorMessage,
|
||||
normalizeWeixinGzhPublishErrorMessage,
|
||||
} from "./publisher-errors";
|
||||
|
||||
describe("publisher error normalization", () => {
|
||||
@@ -23,6 +27,24 @@ describe("publisher error normalization", () => {
|
||||
expect(normalizeQiehaoPublishErrorMessage("publish rejected", -5022)).toBe(QIEHAO_REAL_NAME_AUTH_MESSAGE);
|
||||
});
|
||||
|
||||
it("normalizes publisher login-state failures", () => {
|
||||
expect(normalizePublisherErrorMessage("wangyihao_not_logged_in")).toBe(
|
||||
"网易号账号登录态已失效,请重新登录该平台后再重试。",
|
||||
);
|
||||
expect(normalizePublisherErrorMessage("Error: weixin_gzh_not_logged_in")).toBe(
|
||||
"微信公众号账号登录态已失效,请重新登录该平台后再重试。",
|
||||
);
|
||||
expect(normalizePublisherErrorMessage("qiehao_cookie_missing")).toBe(
|
||||
"企鹅号账号登录态已失效,请重新登录该平台后再重试。",
|
||||
);
|
||||
});
|
||||
|
||||
it("uses a generic Chinese message for unknown publisher login-state failures", () => {
|
||||
expect(normalizePublisherLoginErrorMessage("unknown_platform_not_logged_in")).toBe(
|
||||
PUBLISH_ACCOUNT_NOT_LOGGED_IN_MESSAGE,
|
||||
);
|
||||
});
|
||||
|
||||
it("normalizes Wangyihao token missing failures", () => {
|
||||
expect(normalizePublisherErrorMessage("wangyihao_token_missing")).toBe(WANGYIHAO_TOKEN_MISSING_MESSAGE);
|
||||
expect(normalizeWangyihaoPublishErrorMessage("Error: wangyihao_token_missing")).toBe(
|
||||
@@ -48,6 +70,15 @@ describe("publisher error normalization", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("normalizes Weixin GZH missing public URL failures", () => {
|
||||
expect(normalizePublisherErrorMessage("weixin_gzh_public_url_missing:100000093")).toBe(
|
||||
WEIXIN_GZH_PUBLIC_URL_MISSING_MESSAGE,
|
||||
);
|
||||
expect(normalizeWeixinGzhPublishErrorMessage("Error: weixin_gzh_public_url_missing")).toBe(
|
||||
WEIXIN_GZH_PUBLIC_URL_MISSING_MESSAGE,
|
||||
);
|
||||
});
|
||||
|
||||
it("leaves unknown publisher errors unchanged", () => {
|
||||
expect(normalizePublisherErrorMessage("qiehao_publish_failed")).toBe("qiehao_publish_failed");
|
||||
});
|
||||
|
||||
@@ -1,9 +1,28 @@
|
||||
export const QIEHAO_REAL_NAME_AUTH_MESSAGE = "企鹅号账号未完成实名认证,请先到企鹅号后台完成实名认证后再重试。";
|
||||
export const PUBLISH_ACCOUNT_NOT_LOGGED_IN_MESSAGE = "发布账号登录态已失效,请重新打开平台后台完成登录后再重试。";
|
||||
export const WANGYIHAO_TOKEN_MISSING_MESSAGE = "网易号发布凭证获取失败,请重新打开网易号后台确认登录状态。";
|
||||
export const WANGYIHAO_DRAFT_SAVE_PARAMETER_MESSAGE =
|
||||
"网易号草稿保存失败:参数错误。请检查标题、正文、封面或账号状态后重试。";
|
||||
export const WANGYIHAO_PUBLISH_CLICK_MESSAGE =
|
||||
"网易号草稿已保存,但自动发布未完成。请打开网易号后台确认草稿状态后重试。";
|
||||
export const WEIXIN_GZH_PUBLIC_URL_MISSING_MESSAGE =
|
||||
"微信公众号可能已触发管理员/运营者授权发布,桌面端未能获取到文章外链。请打开公众号后台完成授权发布,并在发表记录中确认文章链接。";
|
||||
|
||||
const PUBLISH_PLATFORM_LABELS: Record<string, string> = {
|
||||
baijiahao: "百家号",
|
||||
bilibili: "bilibili",
|
||||
dongchedi: "懂车帝",
|
||||
jianshu: "简书",
|
||||
juejin: "稀土掘金",
|
||||
qiehao: "企鹅号",
|
||||
smzdm: "什么值得买",
|
||||
sohuhao: "搜狐号",
|
||||
toutiaohao: "头条号",
|
||||
wangyihao: "网易号",
|
||||
weixin_gzh: "微信公众号",
|
||||
zhihu: "知乎",
|
||||
zol: "中关村在线",
|
||||
};
|
||||
|
||||
function normalizeErrorText(value: string | null | undefined): string | null {
|
||||
const trimmed = value?.trim();
|
||||
@@ -42,6 +61,23 @@ export function normalizeQiehaoPublishErrorMessage(
|
||||
return isQiehaoRealNameAuthError(normalized, code) ? QIEHAO_REAL_NAME_AUTH_MESSAGE : normalized;
|
||||
}
|
||||
|
||||
export function normalizePublisherLoginErrorMessage(message: string | null | undefined): string | null {
|
||||
const normalized = normalizeErrorText(message);
|
||||
if (!normalized) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const match = normalized.match(
|
||||
/\b([a-z0-9_]+?)_(not_logged_in|token_missing|cookie_missing|csrf_missing)\b/i,
|
||||
);
|
||||
if (!match) {
|
||||
return normalized;
|
||||
}
|
||||
|
||||
const platformLabel = PUBLISH_PLATFORM_LABELS[match[1]?.toLowerCase() ?? ""];
|
||||
return platformLabel ? `${platformLabel}账号登录态已失效,请重新登录该平台后再重试。` : PUBLISH_ACCOUNT_NOT_LOGGED_IN_MESSAGE;
|
||||
}
|
||||
|
||||
export function normalizeWangyihaoPublishErrorMessage(message: string | null | undefined): string | null {
|
||||
const normalized = normalizeErrorText(message);
|
||||
if (!normalized) {
|
||||
@@ -63,7 +99,21 @@ export function normalizeWangyihaoPublishErrorMessage(message: string | null | u
|
||||
return normalized;
|
||||
}
|
||||
|
||||
export function normalizeWeixinGzhPublishErrorMessage(message: string | null | undefined): string | null {
|
||||
const normalized = normalizeErrorText(message);
|
||||
if (!normalized) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (/\bweixin_gzh_public_url_missing\b/i.test(normalized)) {
|
||||
return WEIXIN_GZH_PUBLIC_URL_MISSING_MESSAGE;
|
||||
}
|
||||
return normalized;
|
||||
}
|
||||
|
||||
export function normalizePublisherErrorMessage(message: string | null | undefined): string | null {
|
||||
const qiehaoMessage = normalizeQiehaoPublishErrorMessage(message);
|
||||
return normalizeWangyihaoPublishErrorMessage(qiehaoMessage);
|
||||
const wangyihaoMessage = normalizeWangyihaoPublishErrorMessage(qiehaoMessage);
|
||||
const loginMessage = normalizePublisherLoginErrorMessage(wangyihaoMessage);
|
||||
return normalizeWeixinGzhPublishErrorMessage(loginMessage);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user