fix(common): ValidationError 改为继承 Error 修复 Hermes 校验崩溃

- Babel 转译子类 apply 调用原生 ZodError 在 Hermes 抛 TypeError,掩盖真实校验失败
- unexpected 分支补安全诊断日志(构造名+截断消息)
- xuqm-bundles.gradle 将 file: 依赖的 src/metro 纳入任务输入
这个提交包含在:
XuqmGroup 2026-07-21 01:10:41 +08:00
父节点 507ce3d2ee
当前提交 d009c3b616
共有 4 个文件被更改,包括 33 次插入4 次删除

查看文件

@ -64,6 +64,17 @@ export function createAxiosDiagnostic(error: AxiosError): SafeApiDiagnostic {
}
}
/**
* axios
* causestackconfig
*/
export function createUnexpectedDiagnostic(error: unknown): string {
if (error instanceof Error) {
return `${error.name}: ${error.message.slice(0, 200)}`
}
return typeof error
}
type ValidationCause = {
issues: z.ZodIssue[]
response: AxiosResponse<unknown>

查看文件

@ -10,6 +10,7 @@ import { z } from 'zod'
import {
createAxiosDiagnostic,
createResponseDiagnostic,
createUnexpectedDiagnostic,
createValidationDiagnostic,
} from './diagnostics'
import { RequestError } from './errors'
@ -123,7 +124,13 @@ export const useApi = <S extends z.ZodTypeAny, T extends z.infer<S> = z.infer<S>
return Promise.reject(new RequestError('网络请求失败', 'AxiosError', thrownError))
}
console.error('[XuqmAPI] unexpected request failure')
console.error(
'[XuqmAPI] unexpected request failure',
createUnexpectedDiagnostic(thrownError),
)
if (thrownError instanceof Error && thrownError.stack) {
console.error('[XuqmAPI] unexpected request failure stack', thrownError.stack)
}
return Promise.reject(new RequestError('网络请求失败', 'OtherError', thrownError))
},
)

查看文件

@ -21,13 +21,21 @@ export interface RequestOptions {
// ─── 内部 ValidationError对齐 @szyx-mobile/use-axios 的 ValidationError────
export class ValidationError<T = unknown, D = unknown> extends z.ZodError {
// 不能 extends z.ZodErrorzod v4 的 ZodError 是 $constructor 工厂函数,
// 其自定义 Symbol.hasInstance 要求实例已初始化 _zod.traits。Babel 转译的子类
// 在 super() 之前先执行 _classCallCheck(this, ValidationError),此时 _zod 尚不
// 存在,instanceof 返回 false,直接抛 “Cannot call a class as a function”,
// 把真实的校验失败掩盖成非预期错误。
export class ValidationError<T = unknown, D = unknown> extends Error {
public readonly issues: z.ZodIssue[]
constructor(
issues: z.ZodIssue[],
public readonly response: AxiosResponse<T, D>,
) {
super(issues)
super(issues[0]?.message ?? 'ValidationError')
this.name = 'ValidationError'
this.issues = issues
}
}

查看文件

@ -142,9 +142,12 @@ def prepareXuqmBundles = tasks.register(
include("*.mjs")
})
// registry baselinefile:
// Gradle native baseline
// Gradle native baseline
// JS/TS 源码决定 bundle 内容,android/ios native baseline
xuqmLocalDependencyDirectories.each { dependencyDirectory ->
sourceFiles.from(project.fileTree(dependencyDirectory) {
include("src/**")
include("metro/**")
include("android/**")
include("ios/**")
include("*.podspec")