uni-app 开源仓库 UTS 内置对象 Error 完全指南:错误创建、属性详解与跨端异常处理
【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址: https://gitcode.com/gh_mirrors/un/uni-app
导读
本文以 uni-app 开源仓库 docs/uts/buildin-object-api/error.md 为核心,系统讲解 UTS(uni type script)语言中的内置对象Error:包括运行时错误的产生机制、message与cause两个实例属性的语义、三种创建Error的写法,以及结合throw/try...catch的完整异常处理流程。同时结合仓库源码与测试用例,深入剖析Error在 Android(Kotlin)平台的编译产物UTSError、与框架级UniError的区别,以及跨端错误处理的最佳实践。读完本文,你将能够在 UTS 插件与 uvue 页面中正确创建、包装、捕获与传播错误。
Error 是什么
在 UTS 中,当运行时错误产生时,Error对象会被抛出(throw)。同时,Error也可作为开发者自定义异常的基础对象,通过继承或直接实例化来表达业务层面的错误语义。
UTS 是一门强类型、可编译到多平台原生语言的现代编程语言(详见 docs/uts/README.md):
- Web 平台 / 小程序:编译为 JavaScript;
- Android 平台:编译为 Kotlin(uts 插件内);
- iOS 平台:编译为 Swift(uts 插件内);
- 鸿蒙 OS 平台:编译为 ArkTS(uts 插件内)。
由于Error属于 UTS 的内置对象(buildin object),它在不同平台的编译产物并不相同。这一点在仓库文档 docs/plugin/uts-plugin-hybrid.md 的「uts 和 kotlin 对象映射表」中有明确记录:
| UTS 内置对象 | 编译成的原生类名 |
|---|---|
| Array | io.dcloud.uts.UTSArray |
| Number | kotlin.Number |
| String | kotlin.String |
| Date | io.dcloud.uts.Date |
| Promise | io.dcloud.uts.UTSPromise |
| Error | io.dcloud.uts.UTSError |
也就是说,在 Android 平台(Kotlin)上,你写的new Error(...)最终会实例化为io.dcloud.uts.UTSError;在 iOS(Swift)、Web(JS)等其他平台则对应各自的错误类型实现。理解这一点,有助于你在 uts 插件与原生代码(Kotlin/Swift)交互时,正确识别和转换错误对象。
实例属性
Error实例主要暴露两个属性:message与cause。
message:错误消息
message表示错误消息文本。对于开发者手动创建的Error对象,message的值就是构造函数第一个参数传入的字符串;对于运行时(如引擎或系统)抛出的错误,message则是运行时提供的描述信息。
仓库中的自动化测试用例 examples/hello-uts/uni_modules/uts-tests/utssdk/Error.uts 直接验证了这一行为:
test('message', () => { try { throw new Error('Whoops!') } catch (e) { expect((e as Error).message).toEqual("Whoops!"); } })该用例展示了两个要点:
- 通过
new Error('Whoops!')抛出的错误,其message属性严格等于构造参数'Whoops!'; - 在
catch分支中,捕获到的异常对象e需要显式断言为Error类型((e as Error))后才能安全访问message,这体现了 UTS 的强类型约束——与 TypeScript 类似,捕获的异常需要类型收窄后才能使用其具体成员。
cause:原始错误原因
cause用于保存「导致该错误的具体原始原因」。典型场景是错误包装(error wrapping):
- 底层调用抛出某个原始错误;
- 上层捕获后,将其包装进一个更具体、对调用方更有用的错误;
- 通过
cause字段仍可回溯访问到原始错误,避免丢失根因信息。
这是 JS/TS 生态中常见的错误链路追溯模式。在 UTS 中该语义与 TypeScript 保持一致:new Error(message, { cause: 原始错误 })。
创建 Error
UTS 支持以下三种创建方式(与 docs/uts/buildin-object-api/error.md 保持一致):
// 直接创建(无消息) let error = new Error(); // 指定 message let err = new Error('Whoops!'); // 同时指定 message 和 cause(错误包装) let otherError = new Error("Connecting to database failed.", { cause: err });第一种方式创建无消息的空错误,适用于仅表达「发生了一个错误」而不需要细节的场合;第二种是最常用的写法;第三种用于错误包装,将底层异常作为cause挂载到新错误上,形成可追溯的错误链。
抛异常与捕获异常
仅创建Error对象不会产生任何效果,必须通过throw抛出、由try...catch捕获,异常处理链路才完整。相关语法在仓库文档 docs/uts/exception.md 中有系统说明。
throw:抛出异常
使用throw表达式抛出一个异常,通常搭配new Error(...):
throw new Error("Hi There!");在仓库的 uvue 示例页面 examples/hello-uvue/pages/error/throw-error/throw-error-composition.uvue 中,展示了多种触发错误的方式:页面生命周期回调中直接抛出、按钮事件处理器中抛出、以及setTimeout定时回调中抛出:
onReady(() => { throw new Error('error in error composition page onReady') }) const triggerError = () => { throw new Error('trigger error in throw error composition page') } const triggerTimeoutError = () => { setTimeout(() => { throw new Error('setTimeout trigger error in throw error composition page') }, 10) }该示例页面同样提供了选项式 API 的对照实现(见 throw-error-options.uvue),说明无论采用组合式还是选项式写法,throw new Error(...)的用法完全一致。
try...catch...finally:捕获与兜底
使用try...catch表达式捕获异常,finally块可选:
try { // 一些代码 } catch (e: Error) { // 处理程序 } finally { // 可选的 finally 块 }三段式语义如下:
try块:存放可能抛出异常的代码;catch (e: Error):捕获并处理异常,可对异常对象做类型标注后进行针对性处理;finally块:无论是否发生异常都会执行,适合释放资源、恢复状态等收尾逻辑。
iOS 平台注意事项
一个重要的跨端差异:在 iOS 平台,由于 Swift 的语法特性,无法直接使用try...catch。iOS 平台上使用try的特殊语法详见 docs/plugin/uts-for-ios.md 中关于 try 的章节。如果插件需要同时兼容 iOS 与其他平台,建议将try...catch代码置于条件编译中,或采用 Swift 侧的错误处理约定。
平台编译差异:UTSError 与 UniError
Android 平台的 UTSError
前文已述,Error在 Android(Kotlin)平台编译为io.dcloud.uts.UTSError(记录于 docs/plugin/uts-plugin-hybrid.md 与 docs/uts/buildin-object-api/error.md 的 Bug & Tips 一节)。
这意味着在编写 uts 插件时,若需要在 Kotlin 原生代码与 UTS 环境之间互传错误对象,应留意该映射关系:原生侧捕获到UTSError,与 UTS 侧的Error是同一个对象;反之亦然。在原生与 UTS 环境互传数据时,文档建议尽量转换为标准内置对象后再传递,以规避平台差异(见 docs/plugin/uts-plugin-hybrid.md)。
框架级错误对象 UniError
除语言层面的Error外,uni-app 框架在 API 层还提供了UniError对象,用于描述 API 调用失败的具体信息(如errSubject、errCode、errMsg),其结构规范见 docs/err-spec.md。两者定位不同:
Error:UTS 语言内置对象,面向运行时错误与自定义异常的通用错误;UniError:uni-app 框架 API 层的统一错误返回体,常用于fail回调参数。
仓库测试 examples/hello-uts/uni_modules/uts-tests/utssdk/Error.uts 同时覆盖了两者:
test('UniError', () => { expect(new UniError().message).toEqual('') expect(new UniError('Whoops!').message).toEqual('Whoops!') })从该用例可以看出,UniError同样支持无参构造与携带消息构造,且其message语义与Error一致。在 docs/api/get-file-system-manager.md 中还能看到实战组合用法——用new UniError(res.errSubject, res.errCode, res.errMsg)将 API 回调中的错误信息重构为完整的UniError对象,便于统一处理和上报。
错误包装与 cause 链的实战模式
结合cause属性与try...catch,可以构建标准的错误包装链路。设底层函数connectDatabase()可能抛出连接错误,上层服务捕获后包装为带有业务语义的错误,同时保留根因:
function connectDatabase() { // 底层可能抛错 throw new Error('connection refused'); } function queryUser() { try { connectDatabase(); } catch (e) { // 包装:向上层抛出更具体的错误,并通过 cause 保留原始错误 throw new Error("queryUser failed: database unavailable.", { cause: e }); } } try { queryUser(); } catch (e) { const err = e as Error; console.log(err.message); // 输出包装后的业务错误消息 console.log(err.cause); // 可回溯到原始连接错误 }这种模式的价值在于:上层调用方只需处理统一包装后的错误类型与消息,而排查问题时仍能通过cause一路回溯到最底层的真实根因,避免错误信息在多层传递中被稀释。
使用注意与最佳实践
结合原文档的 Bug & Tips 与仓库内相关文档,归纳以下实践要点:
- 牢记平台映射:
Error在 Android 平台编译为io.dcloud.uts.UTSError,编写 uts 插件与 Kotlin 原生代码交互时需注意类名对应关系(docs/plugin/uts-plugin-hybrid.md)。 - iOS 的 try 限制:iOS(Swift)平台无法直接使用
try...catch,需要参考 docs/plugin/uts-for-ios.md 的 try 语法,必要时使用条件编译隔离平台差异。 - 捕获后做类型断言:
catch分支中访问错误成员前,先用(e as Error)进行类型收窄,这是 UTS 强类型约束下的标准写法(参见 docs/uts/uts_diff_ts.md 中 uts 与 ts 差异的说明)。 - 区分 Error 与 UniError:语言内部逻辑、自定义异常用
Error;与 uni-app API 交互、处理fail回调错误信息时用UniError,后者携带errSubject/errCode/errMsg等结构化字段(docs/err-spec.md)。 - 善用 cause 保持错误链:包装错误时务必通过
{ cause: 原始错误 }挂载根因,保证多层调用后仍可完整回溯。 - 消息要可读、可定位:为
new Error(...)提供准确、包含上下文信息的 message,便于日志排查;页面与插件中抛出的错误消息应能定位到具体页面、生命周期或操作(参考 throw-error-composition.uvue 的命名风格)。
深入阅读
- UTS 内置对象 Error 官方文档:本文的直接依据;
- UTS 异常处理(throw / try...catch):异常抛出的完整语法;
- UTS 语言介绍与编译目标:了解各平台编译产物;
- uts 与 ts 的差异:强类型约束与跨端限制;
- UTS 与 Kotlin 对象映射表:Error → UTSError 的类名对应;
- 错误规范 err-spec:UniError 结构定义;
- Error 自动化测试用例:message 与 UniError 的行为验证;
- uvue 页面抛出错误示例:页面场景下的 throw 实践。
【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址: https://gitcode.com/gh_mirrors/un/uni-app
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考