修复登录失败分流把空文案的业务变体误判为需上报
- resolveClientAuthFailure 改用 clientAuthErrorKind 判分流,不再用 clientAuthErrorNotice 是否为 null 当判据 - 空文案的 input/session 变体改为给兜底提示、不进错误池,保持"预期拒绝永不进池"的约束 - clientAuthErrorNotice 文档注明 null 同时表示 fault 与空文案,不能当分流判据 - clientAuthHost.test.ts 增加空文案业务变体的分流用例
This commit is contained in:
@@ -1,6 +1,10 @@
|
|||||||
import type { AuthUser } from '../../../../packages/shared/src/contracts/auth';
|
import type { AuthUser } from '../../../../packages/shared/src/contracts/auth';
|
||||||
import { resolveTauriInvoke } from '../app/tauri';
|
import { resolveTauriInvoke } from '../app/tauri';
|
||||||
import { clientAuthErrorNotice, isClientAuthError } from './clientAuthError';
|
import {
|
||||||
|
clientAuthErrorKind,
|
||||||
|
clientAuthErrorNotice,
|
||||||
|
isClientAuthError,
|
||||||
|
} from './clientAuthError';
|
||||||
import { subscribeTauriEvent } from './tauriEventSubscription';
|
import { subscribeTauriEvent } from './tauriEventSubscription';
|
||||||
|
|
||||||
/** Rust 认证态事件:只承载状态投影,不含 token 或 refresh 凭据。 */
|
/** Rust 认证态事件:只承载状态投影,不含 token 或 refresh 凭据。 */
|
||||||
@@ -57,7 +61,8 @@ export function getClientAuthErrorMessage(error: unknown, fallback: string) {
|
|||||||
* 只显示 Rust 文案;`report` 是系统变体 / 未识别变体 / 非结构化拒绝,显示文案之外还要带上下文
|
* 只显示 Rust 文案;`report` 是系统变体 / 未识别变体 / 非结构化拒绝,显示文案之外还要带上下文
|
||||||
* 交给错误池(见 [`captureClientError`](./errorReporting.ts))。
|
* 交给错误池(见 [`captureClientError`](./errorReporting.ts))。
|
||||||
*
|
*
|
||||||
* 判定只看类型化的 `type`,不做任何文案匹配;这条规则是"输错一次密码不该被引导上报"的判据。
|
* 判定只看类型化的 `type`(`clientAuthErrorKind`),不做任何文案匹配;这条规则是
|
||||||
|
* "输错一次密码不该被引导上报"的判据。
|
||||||
*/
|
*/
|
||||||
export type ClientAuthFailureResolution =
|
export type ClientAuthFailureResolution =
|
||||||
| { kind: 'notice'; message: string }
|
| { kind: 'notice'; message: string }
|
||||||
@@ -68,8 +73,16 @@ export function resolveClientAuthFailure(
|
|||||||
fallback: string,
|
fallback: string,
|
||||||
): ClientAuthFailureResolution {
|
): ClientAuthFailureResolution {
|
||||||
const structured = isClientAuthError(error);
|
const structured = isClientAuthError(error);
|
||||||
const notice = structured ? clientAuthErrorNotice(structured) : null;
|
// 分流判据是 `clientAuthErrorKind`,不是"有没有提示":`clientAuthErrorNotice` 对空文案也返回
|
||||||
if (notice !== null) return { kind: 'notice', message: notice };
|
// `null`,拿它当判据会把"Rust 给了可识别的 input/session 变体、但文案为空"错当成 fault 上报。
|
||||||
|
if (structured && clientAuthErrorKind(structured) !== 'fault') {
|
||||||
|
return {
|
||||||
|
kind: 'notice',
|
||||||
|
message:
|
||||||
|
clientAuthErrorNotice(structured) ??
|
||||||
|
getClientAuthErrorMessage(error, fallback),
|
||||||
|
};
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
kind: 'report',
|
kind: 'report',
|
||||||
message: getClientAuthErrorMessage(error, fallback),
|
message: getClientAuthErrorMessage(error, fallback),
|
||||||
|
|||||||
@@ -51,7 +51,10 @@ export function clientAuthErrorKind(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户可读的提示:`input` / `session` 原样使用 Rust 生成的那一份文案;`fault` 返回 `null`,
|
* 用户可读的提示:`input` / `session` 原样使用 Rust 生成的那一份文案;`fault` 返回 `null`,
|
||||||
* 表示"调用方处理不了,交给错误池"。空文案按"没有提示"处理,避免调用方拿空串当提示显示。
|
* 表示"调用方处理不了,交给错误池"。空文案也按"没有提示"处理,避免调用方拿空串当提示显示。
|
||||||
|
*
|
||||||
|
* **`null` 同时表示这两件事,所以它不是分流判据**:判定"要不要进错误池"必须用
|
||||||
|
* [`clientAuthErrorKind`],只有 `fault` 才上报;否则一个文案为空的可识别变体会被误报。
|
||||||
*/
|
*/
|
||||||
export function clientAuthErrorNotice(error: ClientAuthError): string | null {
|
export function clientAuthErrorNotice(error: ClientAuthError): string | null {
|
||||||
if (clientAuthErrorKind(error) === 'fault') return null;
|
if (clientAuthErrorKind(error) === 'fault') return null;
|
||||||
|
|||||||
@@ -210,6 +210,14 @@ test('登录失败分流只看类型化变体:业务拒绝给提示,系统
|
|||||||
'登录失败',
|
'登录失败',
|
||||||
),
|
),
|
||||||
).toEqual({ kind: 'notice', message: '登录已失效,请重新登录' });
|
).toEqual({ kind: 'notice', message: '登录已失效,请重新登录' });
|
||||||
|
// 文案为空的可识别变体仍按"用户可改"处理:给兜底提示,不进错误池
|
||||||
|
// (分流判据是 kind,不是"有没有提示文案")。
|
||||||
|
expect(
|
||||||
|
resolveClientAuthFailure(
|
||||||
|
{ type: 'phoneNumberInvalid', message: ' ' },
|
||||||
|
'登录失败',
|
||||||
|
),
|
||||||
|
).toEqual({ kind: 'notice', message: '登录失败' });
|
||||||
// 系统变体与未识别变体:显示 Rust 文案,同时交给错误池。
|
// 系统变体与未识别变体:显示 Rust 文案,同时交给错误池。
|
||||||
expect(
|
expect(
|
||||||
resolveClientAuthFailure(
|
resolveClientAuthFailure(
|
||||||
|
|||||||
Reference in New Issue
Block a user