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
- 新增 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 用例
90 lines
2.8 KiB
TypeScript
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();
|
|
});
|
|
});
|