fix(canvas): 模型生成 - 保留安全的上游失败原因并展示到用户卡片
This commit is contained in:
@@ -15,7 +15,7 @@ export function generationFailureMetadata(error: unknown, prompt: string): Gener
|
||||
const raw = rawGenerationError(error);
|
||||
if (!isContentModerationError(raw)) return { errorDetails: generationErrorMessage(error) };
|
||||
return {
|
||||
errorDetails: CONTENT_MODERATION_MESSAGE,
|
||||
errorDetails: generationErrorMessage(error),
|
||||
generationErrorCode: CONTENT_MODERATION_ERROR_CODE,
|
||||
failedPromptFingerprint: generationPromptFingerprint(prompt),
|
||||
};
|
||||
@@ -23,23 +23,34 @@ export function generationFailureMetadata(error: unknown, prompt: string): Gener
|
||||
|
||||
export function generationErrorMessage(error: unknown) {
|
||||
const raw = rawGenerationError(error);
|
||||
if (isContentModerationError(raw)) return CONTENT_MODERATION_MESSAGE;
|
||||
if (isContentModerationError(raw)) return contentModerationMessage(raw);
|
||||
|
||||
const providerMessage = extractStructuredProviderMessage(raw) || extractWrappedProviderMessage(raw);
|
||||
const displayMessage = providerMessage || raw;
|
||||
if (isContentModerationError(displayMessage)) return CONTENT_MODERATION_MESSAGE;
|
||||
if (isContentModerationError(displayMessage)) return contentModerationMessage(displayMessage);
|
||||
const resourceStorageMessage = resourceStorageFailureMessage(raw) || resourceStorageFailureMessage(displayMessage);
|
||||
if (resourceStorageMessage) return resourceStorageMessage;
|
||||
if (isNetworkFailure(displayMessage)) return NETWORK_ERROR_MESSAGE;
|
||||
if (!providerMessage) {
|
||||
if (hasHttpStatus(raw, 429)) return "服务当前繁忙,请稍后重试。";
|
||||
if (hasHttpStatus(raw, 401, 403)) return "生成服务鉴权失败,请检查渠道配置。";
|
||||
if (hasHttpStatus(raw, 404)) return "生成服务地址不可用,请检查渠道配置。";
|
||||
if (hasHttpStatus(raw, 500, 502, 503, 504) || containsInfrastructureDetails(raw)) return NETWORK_ERROR_MESSAGE;
|
||||
if (!displayMessage.includes(";上游:")) {
|
||||
if (hasHttpStatus(raw, 429)) return "服务当前繁忙,请稍后重试。";
|
||||
if (hasHttpStatus(raw, 401, 403)) return "生成服务鉴权失败,请检查渠道配置。";
|
||||
if (hasHttpStatus(raw, 404)) return "生成服务地址不可用,请检查渠道配置。";
|
||||
if (hasHttpStatus(raw, 500, 502, 503, 504)) return NETWORK_ERROR_MESSAGE;
|
||||
}
|
||||
if (containsInfrastructureDetails(raw)) return NETWORK_ERROR_MESSAGE;
|
||||
}
|
||||
return displayMessage || DEFAULT_GENERATION_ERROR_MESSAGE;
|
||||
}
|
||||
|
||||
function contentModerationMessage(raw: string) {
|
||||
const detailIndex = raw.indexOf(";上游:");
|
||||
// 保留服务端过滤后的拒绝原因,同时保持平台审核的积分提示及重试保护。
|
||||
return detailIndex >= 0 && !containsInfrastructureDetails(raw)
|
||||
? CONTENT_MODERATION_MESSAGE + raw.slice(detailIndex)
|
||||
: CONTENT_MODERATION_MESSAGE;
|
||||
}
|
||||
|
||||
export function generationErrorCode(error: unknown) {
|
||||
if (error && typeof error === "object" && "code" in error && typeof (error as { code?: unknown }).code === "string") {
|
||||
const code = (error as { code: string }).code;
|
||||
|
||||
24
web/test/generation-error-details.test.ts
Normal file
24
web/test/generation-error-details.test.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { CONTENT_MODERATION_MESSAGE, generationErrorMessage, generationFailureMetadata } from "../src/lib/generation-error";
|
||||
|
||||
describe("safe upstream error details", () => {
|
||||
const detail = "非常抱歉,生成的图片可能违反了关于裸露、色情或情色内容的防护限制。请重试或修改提示语。";
|
||||
test("keeps the specific image rejection on the card", () => {
|
||||
const message = `模型服务拒绝了请求,请检查模型和参数;上游:${detail}`;
|
||||
expect(generationErrorMessage(new Error(message))).toBe(message);
|
||||
});
|
||||
test("does not replace a safe upstream message with a generic HTTP hint", () => {
|
||||
const message = `模型服务暂时不可用(HTTP 500);上游:${detail}`;
|
||||
expect(generationErrorMessage(message)).toBe(message);
|
||||
expect(generationErrorMessage("模型服务暂时不可用(HTTP 500)")).toBe("网络异常。");
|
||||
});
|
||||
test("keeps details when moderation metadata is stored", () => {
|
||||
const message = `内容审核未通过;上游:${detail}`;
|
||||
const metadata = generationFailureMetadata(message, "test prompt");
|
||||
expect(metadata.errorDetails).toBe(`${CONTENT_MODERATION_MESSAGE};上游:${detail}`);
|
||||
expect(metadata.generationErrorCode).toBe("sensitive_words_detected");
|
||||
});
|
||||
test("upstream marker does not bypass URL hiding", () => {
|
||||
expect(generationErrorMessage("模型服务请求失败;上游:https://private.test")).toBe("网络异常。");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user