WebAssembly.Exception
Baseline Widely available *
This feature is well established and works across many devices and browser versions. It’s been available across browsers since May 2022.
* Some parts of this feature may have varying levels of support.
备注: 此特性在 Web Worker 中可用。
WebAssembly.Exception
对象表示一个从 WebAssembly 向 JavaScript 抛出、或者从 JavaScript 向 WebAssembly 的异常处理器抛出的运行时异常。
构造函数接受一个 WebAssembly.Tag
、一个由值组成的数组和一个 options
对象作为参数。标签唯一地定义了异常的类型,包括异常的参数的顺序和参数的数据类型。访问抛出的异常的参数所用的标签要求和用于创建 Exception
的标签相同。提供了用于测试异常是否和特定的标签匹配的方法,也提供了通过索引获取特定值的方法(如果异常匹配上指定的标签的话)。
当关联的标签共享时,JavaScript 和其他客户端代码仅能访问 WebAssembly 异常值,反之亦然(你不能仅使用恰好定义了相同数据类型的其他标签)。没有匹配的标签,也可以捕获以及重新抛出异常,但是不能对其进行检查。
为了让异常抛出更快,从 WebAssembly 抛出的异常通常不包括堆栈跟踪。需要提供堆栈跟踪的 WebAssembly 代码必须在调用创建异常的 Javascript 函数时,在构造函数中传递 options.traceStack=true
参数。然后构造函数可能会返回一个将堆栈跟踪附着到 stack
属性的异常。
构造函数
WebAssembly.Exception()
创建一个新的
WebAssembly.Exception
对象。
实例方法
Exception.prototype.is()
测试异常是否匹配某个特定的标签。
Exception.prototype.getArg()
返回与特定标签相匹配的异常的数据字段。
实例属性
Exception.prototype.stack
非标准返回异常的堆栈跟踪,或者
undefined
。
示例
这个示例展示如何定义一个标签并将其导入到模块,然后用它抛出一个在 JavaScript 中被捕获的异常。
思考下面的 WebAssembly 代码,假设其被编译为 example.wasm 文件。
- 模块导入一个标签,内部引用为
$tagname
并有一个单独的i32
参数。tag 期望使用模块extmod
和标签exttag
传递标签。 $throwException
函数使用throw
指令抛出一个异常,接收$tagname
和标签的参数。- 模块导出一个抛出异常值为“42”的函数
run()
。
(module ;; 导入的标签在这引用为 $tagname (import "extmod" "exttag" (tag $tagname (param i32))) ;; $throwException 函数将 i32 参数作为 $tagname 异常抛出 (func $throwException (param $errorValueArg i32) local.get $errorValueArg throw $tagname ) ;; 导出调用 $throwException 的函数“run” (func (export "run") i32.const 42 call $throwException ) )
下面的代码调用 WebAssembly.instantiateStreaming
导入 example.wasm 文件,传入的“导入对象”(importObject
)中包含一个新的、名为 tagToImport
的 WebAssembly.Tag
。导入的对象用匹配 WebAssembly 代码中 import
语句的属性定义一个对象。
一旦实例化文件,代码就调用导出的 WebAssembly run
方法,该方法会立即抛出一个异常。
const tagToImport = new WebAssembly.Tag({ parameters: ["i32"] }); // 注意:导入对象属性要匹配 WebAssembly import 语句! const importObject = { extmod: { exttag: tagToImport, }, }; WebAssembly.instantiateStreaming(fetch("example.wasm"), importObject) .then((obj) => { console.log(obj.instance.exports.run()); }) .catch((e) => { console.error(e); // 检查我们是否有该异常对应的正确标签 // 如果有的话,使用 getArg() 检查其内容 if (e.is(tagToImport)) { console.log(`getArg 0 : ${e.getArg(tagToImport, 0)}`); } }); /* 日志输出 example.js:40 WebAssembly.Exception: wasm exception example.js:41 getArg 0 : 42 */
在 JavaScript 中使用 catch
块捕获异常。我们可以看见它是 WebAssembly.Exception
类型,但是如果我们没有正确的标签的话,我们就什么也做不了。
然而,因为我们有一个标签,于是使用 Exception.prototype.is()
检查它是否是正确的那个,又因为它是正确的,于是调用 Exception.prototype.getArg()
读取值“42”。
规范
Specification |
---|
WebAssembly JavaScript Interface: Exception Handling # runtime-exceptions |