catch_all: try_table clause
The catch_all clause catches any exception and pushes nothing to the stack.
Try it
(module
;; Import the error tag and the log function
(tag $my_error (import "env" "my_error") (param i32))
(import "env" "log" (func $log))
(func $try_and_catch (param $value i32)
;; catch_all catches any exception thrown
(block $handler
(try_table (catch_all $handler)
(call $might_throw (local.get $value))
)
(return)
)
;; Call log to notify user that exception has been thrown
call $log
)
;; Function that throws an error of type $my_error
;; when its parameter is less than 0
(func $might_throw (param $value i32)
(local.get $value)
(i32.const 0)
(i32.lt_s)
(if
(then
(i32.const 42)
(throw $my_error)
)
)
)
(export "try_and_catch" (func $try_and_catch))
)
// Define error tag in JS
const myErrorTag = new WebAssembly.Tag({ parameters: ["i32"] });
// Import the tag and the log function into the module
const env = {
my_error: myErrorTag,
log: () => {
console.log("An error was caught!");
},
};
WebAssembly.instantiateStreaming(fetch("{%wasm-url%}"), { env }).then(
// Negative value causes function to throw
(result) => result.instance.exports.try_and_catch(-1),
);
Syntax
catch_all block_identifier
catch_all-
The
catch_allclause. block_identifier-
The identifier for the
blockto branch to when the exception is caught. This can be:- An identifying name, as defined by the identifier of the corresponding block.
- A block index number —
0to identify the innermost block,1for the next innermost, etc.
Type
[] -> []
Binary encoding
| Clause | catch_all type byte |
|---|---|
catch_all |
0x02 |
catch_all is not a standalone clause — instead, it is encoded as a clause within a try_table instruction with a byte of 0x02. A try_table with a single catch_all clause:
(try_table (catch_all $handler) ... )
would be encoded like this:
... 0x01 0x02 0x00 ...
Description
The catch_all clause can be included inside a try_table block to catch any thrown exceptions. When an exception is thrown, the code branches to the specified block.
catch_all is useful when you don't need to rethrow an exception, and you don't want to catch a specific exception, but you do want to report that an exception of some kind has been thrown.
In the case of catch_all, the referenced block doesn't need to declare a result type that matches the exception's payload, because no result is pushed to the stack. In the example shown earlier, the block has no result type declared:
(block $handler
...
)