@autional/shared 0.1.0-rc.39 → 0.1.0-rc.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -661
- package/package.json +1 -1
- package/src/generated/types.ts +2 -0
- package/src/utils/__tests__/error.test.ts +26 -9
- package/src/utils/error.ts +4 -2
package/package.json
CHANGED
package/src/generated/types.ts
CHANGED
|
@@ -4726,6 +4726,7 @@ export interface CheckRoleRequest {
|
|
|
4726
4726
|
/** 检查用户名可用性请求 */
|
|
4727
4727
|
export interface CheckUsernameRequest {
|
|
4728
4728
|
username: string; // Username | @example john_doe
|
|
4729
|
+
tenantId?: string; // 目标租户(地址栏租户优先)
|
|
4729
4730
|
}
|
|
4730
4731
|
|
|
4731
4732
|
/** 检查用户名可用性结果 */
|
|
@@ -5691,6 +5692,7 @@ export interface ReapplyRegistrationRequest {
|
|
|
5691
5692
|
email: string; // Email
|
|
5692
5693
|
invitationCode?: string; // 邀请码
|
|
5693
5694
|
reason?: string; // 申请理由
|
|
5695
|
+
tenantId?: string; // 目标租户(地址栏租户优先)
|
|
5694
5696
|
}
|
|
5695
5697
|
|
|
5696
5698
|
export interface ReapplyRegistrationResponse {
|
|
@@ -4,19 +4,36 @@ import { extractApiError, extractApiErrorMessage } from '../error';
|
|
|
4
4
|
// UP-17-B 回归锁(AC-401):extractApiError message 键链。
|
|
5
5
|
// 后端 Problem 契约(service-core/base/dto/problem.go)为 title 必填 / detail / code / i18n_key,无 message;
|
|
6
6
|
// 只认 message 会把 Problem 类错误整类退化为 defaultMsg。
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
// U380 回归锁:detail 优先于 title,对齐 Problem.GetMessage()(Detail 非空优先)。
|
|
8
|
+
describe('extractApiError message 键链(UP-17-B / AC-401 / U380)', () => {
|
|
9
|
+
it('detail 优先:Problem 契约(title/detail/code)→ 取 detail', () => {
|
|
9
10
|
const err = {
|
|
10
|
-
response: { data: { code: 403, title: '
|
|
11
|
+
response: { data: { code: 403, title: 'Platform Access Denied', detail: '需要平台角色' } },
|
|
11
12
|
};
|
|
12
13
|
const out = extractApiError(err, 'fallback');
|
|
13
|
-
expect(out.message).toBe('
|
|
14
|
+
expect(out.message).toBe('需要平台角色');
|
|
14
15
|
expect(out.code).toBe(403);
|
|
15
16
|
});
|
|
16
17
|
|
|
17
|
-
it('
|
|
18
|
-
const err = { response: { data: {
|
|
19
|
-
expect(extractApiError(err, 'fallback').message).toBe('
|
|
18
|
+
it('title 兜底:无 message/detail 时取 title', () => {
|
|
19
|
+
const err = { response: { data: { title: 'Invalid Request' } } };
|
|
20
|
+
expect(extractApiError(err, 'fallback').message).toBe('Invalid Request');
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('U380:英文 title + 中文 detail → 中文 detail 胜出', () => {
|
|
24
|
+
const err = {
|
|
25
|
+
response: {
|
|
26
|
+
data: {
|
|
27
|
+
code: 61040050,
|
|
28
|
+
title: 'push challenge not found',
|
|
29
|
+
detail: '推送挑战未找到',
|
|
30
|
+
i18n_key: 'error.push_challenge_not_found',
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
const out = extractApiError(err, 'fallback');
|
|
35
|
+
expect(out.message).toBe('推送挑战未找到');
|
|
36
|
+
expect(out.i18nKey).toBe('error.push_challenge_not_found');
|
|
20
37
|
});
|
|
21
38
|
|
|
22
39
|
it('皆无回落 err.message,再皆无回落 defaultMsg', () => {
|
|
@@ -52,8 +69,8 @@ describe('extractApiError i18n_key 透出(AUTH-46)', () => {
|
|
|
52
69
|
};
|
|
53
70
|
const out = extractApiError(err, 'fallback');
|
|
54
71
|
expect(out.i18nKey).toBe('error.oauth_state_missing');
|
|
55
|
-
// message
|
|
56
|
-
expect(out.message).toBe('
|
|
72
|
+
// U380:键链为 message → detail → title
|
|
73
|
+
expect(out.message).toBe('state not found');
|
|
57
74
|
});
|
|
58
75
|
|
|
59
76
|
it('响应拦截器深 camel 后(i18nKey)同样识别', () => {
|
package/src/utils/error.ts
CHANGED
|
@@ -17,13 +17,15 @@ export function extractApiErrorMessage(err: unknown, defaultMsg: string): string
|
|
|
17
17
|
|
|
18
18
|
export function extractApiError(err: unknown, defaultMsg: string): ExtractedApiError {
|
|
19
19
|
// UP-17-B:后端 Problem 契约(service-core/base/dto/problem.go)字段为 title(必填)/ detail / code / i18n_key,
|
|
20
|
-
// **没有 message** —— 只认 message 会把整类后端错误退化成 defaultMsg
|
|
20
|
+
// **没有 message** —— 只认 message 会把整类后端错误退化成 defaultMsg。
|
|
21
|
+
// U380:键链 message → detail → title,对齐 Problem.GetMessage()(Detail 非空优先),
|
|
22
|
+
// 避免英文 title 压过本地化 detail。
|
|
21
23
|
// 继续用 `||`(而非 `??`):空串语义按「缺省」处理,与既有实现一致。
|
|
22
24
|
// AUTH-46:附加透出 i18n_key(响应拦截器深 camel 后为 i18nKey,两者都认)。
|
|
23
25
|
const data = (err as any)?.response?.data;
|
|
24
26
|
return {
|
|
25
27
|
code: data?.code || 'UNKNOWN',
|
|
26
|
-
message: data?.message || data?.
|
|
28
|
+
message: data?.message || data?.detail || data?.title || (err as any)?.message || defaultMsg,
|
|
27
29
|
i18nKey: data?.i18n_key || data?.i18nKey || undefined,
|
|
28
30
|
};
|
|
29
31
|
}
|