Files
Genarrative/apps/ai-game-creator-shell/tests/clientAuthError.test.ts
T
k88936 5013f4385f
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 1m50s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 1m9s
Project CI / Backend tests (pull_request) Failing after 16s
Project CI / Frontend tests (pull_request) Successful in 2m3s
Project CI / Repository checks (pull_request) Failing after 14s
Project CI / AI game creator shell web tests (pull_request) Failing after 1m42s
Project CI / Native shell tests (pull_request) Successful in 5m41s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 10m10s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 11m9s
AGC 前端错误分流基元:ClientActionError 与认证变体分类
- 新增 clientActionError.ts:ClientActionError 承载 source/action/page 上下文与 cause
- 新增 clientAuthError.ts:isClientAuthError 形状读取 + clientAuthErrorKind 的 input/session/fault 分类 + clientAuthErrorNotice 文案
- captureClientError 解包 ClientActionError 的上下文,并优先使用 cause 的栈信息
- getClientAuthErrorMessage 认识结构化拒绝,非 Error 形状不再字符串化成 [object Object]
- 新增 clientAuthError.test.ts,并在 errorReporting.test.ts 用解包用例替换 shouldCaptureClientError 用例
2026-10-01 15:27:31 +08:00

90 lines
2.8 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import {
clientAuthErrorKind,
clientAuthErrorNotice,
isClientAuthError,
} from '../src/services/clientAuthError';
describe('AGC 认证命令错误分流', () => {
it('只按形状读取 Rust 的结构化拒绝,裸字符串与 Error 都不算', () => {
expect(
isClientAuthError({
type: 'phoneOrPasswordMismatch',
message: '手机号或密码错误',
}),
).toEqual({ type: 'phoneOrPasswordMismatch', message: '手机号或密码错误' });
expect(isClientAuthError('手机号或密码错误')).toBeNull();
expect(isClientAuthError(new Error('手机号或密码错误'))).toBeNull();
expect(
isClientAuthError({ type: '', message: '手机号或密码错误' }),
).toBeNull();
expect(isClientAuthError({ type: 'phoneNumberInvalid' })).toBeNull();
expect(isClientAuthError(null)).toBeNull();
});
it('业务输入给提示、会话变体按未登录、系统与未识别变体交给错误池', () => {
expect(
clientAuthErrorKind({
type: 'passwordEntryInputRejected',
message: '密码长度需要在 6 到 128 位之间',
}),
).toBe('input');
expect(
clientAuthErrorKind({
type: 'phoneOrPasswordMismatch',
message: '手机号或密码错误',
}),
).toBe('input');
expect(
clientAuthErrorKind({
type: 'sessionAuthorityRejected',
message: '登录已失效,请重新登录',
}),
).toBe('session');
expect(
clientAuthErrorKind({
type: 'authNetworkUnavailable',
message: '无法连接登录服务',
}),
).toBe('fault');
expect(
clientAuthErrorKind({
type: 'runtimeSessionInstallFailed',
message: '本机运行时会话安装失败',
}),
).toBe('fault');
// 未识别变体按 fault 处理:Rust 加了变体但界面没接,属于缺陷,必须进池。
expect(
clientAuthErrorKind(
isClientAuthError({ type: 'brandNewRejection', message: '新变体' })!,
),
).toBe('fault');
});
it('input / session 原样使用 Rust 文案,fault 与空文案不给提示', () => {
expect(
clientAuthErrorNotice({
type: 'phoneOrPasswordMismatch',
message: '手机号或密码错误',
}),
).toBe('手机号或密码错误');
expect(
clientAuthErrorNotice({
type: 'sessionAuthorityRejected',
message: '登录已失效,请重新登录',
}),
).toBe('登录已失效,请重新登录');
expect(
clientAuthErrorNotice({
type: 'authServiceUnavailable',
status: 503,
message: '登录服务暂时不可用',
}),
).toBeNull();
expect(
clientAuthErrorNotice({ type: 'phoneNumberInvalid', message: ' ' }),
).toBeNull();
});
});