统一客户端维护态错误弹窗
Project CI / AI game creator shell Rust crates (push) Successful in 1m30s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m57s
Project CI / Backend tests (push) Successful in 3m54s
Project CI / Frontend tests (push) Successful in 2m5s
Project CI / Native shell tests (push) Successful in 6m4s
Project CI / AI game creator shell Rust lane 2/2 (push) Successful in 8m14s
Project CI / AI game creator shell Rust lane 1/2 (push) Successful in 9m19s
Project CI / AI game creator shell web tests (push) Successful in 1m23s
Project CI / Repository checks (push) Successful in 1m55s
Project CI / AI game creator shell Rust crates (push) Successful in 1m30s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m57s
Project CI / Backend tests (push) Successful in 3m54s
Project CI / Frontend tests (push) Successful in 2m5s
Project CI / Native shell tests (push) Successful in 6m4s
Project CI / AI game creator shell Rust lane 2/2 (push) Successful in 8m14s
Project CI / AI game creator shell Rust lane 1/2 (push) Successful in 9m19s
Project CI / AI game creator shell web tests (push) Successful in 1m23s
Project CI / Repository checks (push) Successful in 1m55s
客户端维护响应统一识别并广播维护事件 AGC 与网页端根部展示维护大弹窗,收口发布、上传、资源换签和登录错误 补充维护态弹窗测试、类型检查与实施计划说明
This commit is contained in:
@@ -12,6 +12,7 @@ import { getHostRuntime } from './host-bridge/hostBridge';
|
||||
|
||||
const ACCESS_TOKEN_KEY = 'genarrative.auth.access-token.v1';
|
||||
export const AUTH_STATE_EVENT = 'genarrative-auth-state-changed';
|
||||
export const MAINTENANCE_EVENT = 'genarrative-maintenance-detected';
|
||||
const REQUEST_ID_HEADER = 'x-request-id';
|
||||
const API_VERSION_HEADER = 'x-api-version';
|
||||
const ROUTE_VERSION_HEADER = 'x-route-version';
|
||||
@@ -505,6 +506,38 @@ function shouldRetryResponse(
|
||||
);
|
||||
}
|
||||
|
||||
export function isMaintenanceApiError(error: unknown) {
|
||||
return (
|
||||
error instanceof ApiClientError &&
|
||||
(error.code.trim().toUpperCase() === 'MAINTENANCE' ||
|
||||
(error.status === 503 && error.message.includes('维护')))
|
||||
);
|
||||
}
|
||||
|
||||
export function emitMaintenanceNotice(error?: unknown) {
|
||||
if (typeof globalThis.dispatchEvent !== 'function') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (error !== undefined && !isMaintenanceApiError(error)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const detail =
|
||||
error instanceof ApiClientError
|
||||
? {
|
||||
code: error.code,
|
||||
status: error.status,
|
||||
requestId: error.meta.requestId,
|
||||
}
|
||||
: undefined;
|
||||
const event =
|
||||
typeof CustomEvent === 'function'
|
||||
? new CustomEvent(MAINTENANCE_EVENT, { detail })
|
||||
: new Event(MAINTENANCE_EVENT);
|
||||
globalThis.dispatchEvent(event);
|
||||
}
|
||||
|
||||
export function isAbortError(error: unknown) {
|
||||
return (
|
||||
error instanceof Error &&
|
||||
@@ -1001,7 +1034,7 @@ async function buildApiClientError(
|
||||
undefined;
|
||||
const baseMessage = parseApiErrorMessage(responseText, fallbackMessage);
|
||||
|
||||
return new ApiClientError({
|
||||
const error = new ApiClientError({
|
||||
message: requestId
|
||||
? `${baseMessage}(requestId: ${requestId})`
|
||||
: baseMessage,
|
||||
@@ -1024,6 +1057,10 @@ async function buildApiClientError(
|
||||
},
|
||||
responseText,
|
||||
});
|
||||
if (isMaintenanceApiError(error)) {
|
||||
emitMaintenanceNotice(error);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
export async function requestJson<T>(
|
||||
|
||||
Reference in New Issue
Block a user