AIニュース最前線
最新ニュースAI日報Hacker日報週報動画AIツールトレンド企業

AIニュース最前線

世界中のAI最新情報を日本語で毎時更新

最新ニュース日報トレンド企業プレミアムRSS
© 2026 ainew.jp特定商取引法に基づく表記
ニュース一覧元記事を開く
Cloudflare Blog·2026年4月22日 22:00·約16分で読める

Rust Workersの信頼性向上:wasm-bindgenにおけるパニックとアボートリカバリ

#WebAssembly#Rust#エッジコンピューティング#wasm-bindgen#障害耐性
TL;DR

CloudflareはRust WorkersのWebAssembly実行時におけるパニックとアボート時のサンドボックス汚染を解決し、wasm-bindgenへエラー回復機構をアップストリーム化して信頼性を向上させた。

AI深層分析2026年4月22日 23:04
4
重要/ 5段階
深度40%
4
関連度30%
4
実用性20%
4
革新性10%
3

キーポイント

1

初期の障害検知とリカバリー実装

カスタムパニックハンドラーとJavaScript側のProxyラッパーにより、失敗状態を追跡しWebAssemblyモジュールを再初期化する仕組みを0.6版から標準搭載した。

2

panic=unwindとアボート回復機構の統合

単一リクエストの失敗が他のリクエストを汚染するのを防ぐpanic=unwind対応と、アボート発生後の再実行を完全に禁止する回復メカニズムを実装した。

3

ステートフルワークロードへの対応

従来の全再起動方式では失われるメモリ上の状態を保持し、Durable Objectsなどのステートフルな処理でも信頼性の高い実行環境を提供する。

4

オープンソースエコシステムへの貢献

Cloudflareの独自実装をwasm-bindgen組織へアップストリーム化し、Rust Workersユーザー全体に標準的なエラー回復セマンティクスを提供した。

5

...

...

6

Closureのunwind安全性とnew_abortingバリアント

unwind後に参照が残るクロージャはunwind-unsafeなため、安全が保証できない場合はアンワインドせずに即座に終了するClosure::new_abortingバリアントが導入された。

7

panic=unwind時の動作と状態維持

パニックはキャッチされJavaScript側でPanicErrorとして表面化し、非同期エクスポートも適切に拒否される。また、デストラクタが正常に実行され、WASMインスタンスは有効かつ再利用可能な状態を維持する。

影響分析・編集コメントを表示

影響分析

この改善は、エッジコンピューティング環境におけるRustベースのAI推論・処理ワークロードの実用性を決定づける重要な基盤整備である。サンドボックス汚染の解消により、単一リクエストの異常がインフラ全体を停止させるリスクが排除され、運用コストとダウンタイムが劇的に削減される。また、wasm-bindgenへのアップストリーム統合は、RustとWebAssemblyを活用するすべての開発者に標準的な障害耐性をもたらすことで、エコシステム全体の成熟度を加速させる。

編集コメント

エッジAI基盤の安定性を支えるのは、フレームワークの機能だけでなく、予期せぬエラー発生時のリカバリー設計である。Cloudflareが実証した「汚染防止+状態保持」のパターンは、今後AI推論をエッジへ分散する際の標準設計基準となるだろう。

Rust Workers は、Rust を WebAssembly にコンパイルして Cloudflare Workers 上で動作しますが、私たちが確認したところ、WebAssembly にはいくつかの鋭い角(sharp edges)があります。panic や予期せぬ abort が発生すると、ランタイム(runtime)が未定義の状態に陥ることがあります。Rust Workers のユーザーにとって、panic は歴史的に致命的なものであり、インスタンスをポイズン(poisoning)し、場合によっては一定期間 Worker 自体が使用不能(bricking)になる可能性もありました。

私たちはこれらの問題を検出し軽減することができましたが、Rust Worker が予期せず失敗し、それに伴って他のリクエストも失敗する可能性がわずかに残っていました。1 つのリクエストに影響を与える未処理の Rust abort が、兄弟リクエスト(sibling requests)を含むより広範な障害にエスカレートしたり、新しい着信リクエストに影響を及ぼし続けたりするケースもありました。この根本原因は、Rust Workers が依存する Rust-to-JavaScript バインディング(Rust-to-JavaScript bindings)を生成するコアプロジェクトである wasm-bindgen にあり、組み込みのリカバリセマンティクス(recovery semantics)が欠如していたことにありました。

この記事では、最新の Rust Workers がこの abort 起因のサンドボックスポイズン(sandbox poisoning)を解決する包括的な Wasm エラーリカバリをどのように処理するかをご紹介します。この取り組みは、昨年設立された wasm-bindgen 組織内でのコラボレーションの一環として、wasm-bindgen プロジェクト本体にコントリビューションされました。まず panic=unwind サポートにより、1 つの失敗したリクエストが他のリクエストをポイズンしないことを保証し、その後 abort リカバリメカニズム(abort recovery mechanisms)により、Wasm 上の Rust コードが abort 後に再実行されないことを保証しています。

Initial recovery mitigations

私たちのこの分野での信頼性向上に向けた最初の試みは、本番環境の Rust Workers で発生する Rust panic および abort による障害を理解し、封じ込めることに焦点を当てていました。私たちは、Worker 内の失敗状態を追跡し、後続のリクエストを処理する前にアプリケーションの完全な再初期化をトリガーするカスタム Rust panic handler(panic ハンドラ)を導入しました。JavaScript 側では、すべてのエントリポイント(entrypoints)が一貫してカプセル化されるように、Proxy ベースのインディレクション(Proxy-based indirection)を使用して Rust-JavaScript の呼び出し境界をラップする必要がありました。また、障害発生後に WebAssembly モジュール(WebAssembly module)を正しく再初期化できるよう、生成されたバインディングに対して対象的な修正も施しました。

このアプローチはカスタム JavaScript ロジックに依存していましたが、信頼性の高いリカバリが可能であることを実証し、実際に観測されていた永続的な障害モードを排除しました。このソリューションはバージョン 0.6 から workers‑rs ユーザー全員にデフォルトで提供され、以降のセクションで説明するより一般的でアップストリームにマージされた abort リカバリメカニズム(abort recovery mechanisms)の基盤を築きました。

Implementing panic=unwind with WebAssembly Exception Handling

上記で説明したアボート(abort)回復メカニズムは、Workerが失敗から生き残ることを保証しますが、その代償としてアプリケーション全体を再初期化します。ステートレスなリクエストハンドラにとってはこれで問題ありません。しかし、Durable Objectsのようにメモリ内に意味のある状態を保持するワークロードでは、再初期化は状態の完全な消失を意味します。1つのリクエストでの単一のパニック(panic)が、他の並行リクエストで使用されているメモリ内状態をすべて消去してしまう可能性があります。

通常のネイティブなRust環境では、パニックをアンワインド(unwind)でき、デストラクタを実行して状態を失わずにプログラムを回復できます。しかしWebAssemblyでは、歴史的に状況は大きく異なっていました。wasm32-unknown-unknown経由でWasmにコンパイルされるRustはデフォルトでpanic=abort(アボート)設定になるため、Rust Worker内部でのパニックはunreachable命令による突然のトラップを引き起こし、WebAssembly.RuntimeErrorを返してWasmからJSへ終了します。

インスタンスの状態を破棄せずにパニックから回復するためには、wasm-bindgenにおけるwasm32-unknown-unknown向けのpanic=unwind(アンワインド)サポートが必要でした。これは2023年に主要なエンジンで広く採用されたWebAssembly例外処理提案(WebAssembly Exception Handling proposal)によって可能になったものです。

RUSTFLAGS='-Cpanic=unwind' cargo build -Zbuild-stdでコンパイルを開始し、これによりアンワインドサポート付きで標準ライブラリを再構築し、適切なパニックのアンワインドを行うコードを生成します。例えば:

rust
struct HasDropA;
struct HasDropB;
extern "C" {
    fn imported_func();
}

fn some_func() {
    let a = HasDropA;
    let b = HasDropB;
    imported_func();
}

はWebAssemblyに次のようにコンパイルされます:

wasm
try
  call 
catch_all
  call 
  call 
  rethrow
end
call 
call 

これにより、imported_func()がパニックしてもデストラクタは確実に実行されます。同様に、std::panic::catch_unwind(|| some_func())は次のようにコンパイルされます:

wasm
try
  call 
  ;; set result to Ok(return value)
catch
  try
    call 
    ;; set result to Err(panic payload)
  catch_all
    call 
    unreachable
  end
end

これらをエンドツーエンドで動作させるには、wasm-bindgenツールチェーンにいくつかの変更を加える必要がありました。WebAssemblyパーサーのWalrusはtry/catch命令を処理する方法を知っていなかったため、そのサポートを追加しました。また、ディスクリプタインタプリタにも例外処理ブロックを含むコードを評価する方法を教える必要がありました。これにより、panic=unwind設定でフルアプリケーションをビルドできるようになりました。

最後のステップは、wasm-bindgenが生成するエクスポートを修正し、RustとJavaScriptの境界でパニックをキャッチして、それらをJavaScriptのPanicError例外として表面化することでした。一点注意すべき点として:Rustはextern "C"関数をアンワインドする際に外部例外をキャッチしてアボートするため、境界を跨ぐアンワインドを明示的に許可するためにエクスポートにはextern "C-unwind"のマークが必要でした。Futuresの場合、パニックはPanicErrorを伴ってJavaScriptのPromiseを拒否します。

クロージャには特別な注意が必要でした。panic=unwindでビルドされた場合にのみ UnwindSafe をチェックする新しい MaybeUnwindSafe トレイトを通じて、unwind安全性(unwind safety)が適切に検証されるようにしました。しかし、これによりすぐに問題が露見しました。多くのクロージャはunwind後も存続する参照をキャプチャしており、本質的にunwind安全ではありません。コンパイラを満たすためにユーザーが誤ってクロージャを AssertUnwindSafe でラップすることを促してしまう状況を避けるため、unwind安全性が保証できない場合にunwindの代わりにパニック発生時にプロセスを終了する Closure::new_aborting バリアントを追加しました。

パニックunwind(unwinding)を有効にした場合:

エクスポートされたRust関数内のパニックはwasm-bindgenによってキャッチされます

パニックは PanicError 例外としてJavaScriptに表面化します

非同期エクスポートは、返されたプロミスを PanicError で拒否します

Rustのデストラクタが正しく実行されます

WebAssemblyインスタンスは有効かつ再利用可能であり続けます

このアプローチの詳細およびwasm-bindgenでの使用方法は、Wasm Bindgenの最新ガイドページ「Catching Panics」で解説されています。

abortリカバリ(回復処理)

panic=unwindのサポートがあっても、abort(強制終了)は依然として発生します。よくある原因の一つはメモリ不足エラーです。abortではunwindができないため、状態の完全な回復は不可能ですが、無効な状態が後続のリクエストでエラーを引き起こすのを防ぐため、少なくとも将来の操作に対してabortを検出し、リカバリすることは可能です。

パニックunwindのサポートは、abortリカバリにおいて新たな問題をもたらしました。Wasmからエラーを受信した際、それがextern "C-unwind" 外部例外(foreign exception)に起因するものか、それとも本物のabortなのかを判別できません。WebAssemblyにおけるabortには様々な形態があります。

これを技術的に解決する方法として、明確にabortであるエラーすべてにマークを付けるか、明確にunwindであるエラーすべてにマークを付けるかの2つの選択肢がありました。どちらでも機能しましたが、後者を選択しました。すでに外部例外処理で生のWATレベル(WebAssemblyテキスト形式)のException Handling命令を直接使用していたため、abortするunwind安全でない例外と区別するために、外部例外にexceptionタグを実装する方が容易だと判断しました。

WebAssembly Exception Handlingにおけるこの Exception.Tag 機能のおかげで回復可能エラーと回復不可能エラーを明確に区別できるようになったため、新たなabortハンドラおよびabort再入ガード(reentrancy guards)の両方を統合することができました。

初期化時に使用できる新しいabortフック set_on_abort を用いて、プラットフォーム組み込みのニーズに応じて適切にリカバリするハンドラをアタッチすることができます。

パニック(panic)とアボート(abort)のハンドリングを強化することは、無効な実行状態を回避する上で極めて重要です。WebAssembly(Wasm)では、Wasm が JavaScript(JS)を呼び出し、JavaScript(JS)が任意の深さで Wasm に再進入できるなど、深く交差するコールスタック(call stacks)が許可されます。同時に、複数のタスクが同じインスタンス内で動作することもあります。以前は、1つのタスクやネストされたスタックで発生したアボート(abort)が、JS を介して上位のスタックを無効化することが保証されておらず、未定義動作(undefined behavior)を引き起こす可能性がありました。実行モデル(execution model)を確実に保証するためには細心の注意が必要であり、この分野への貢献は現在も継続しています。

アボート(abort)は決して望ましいものではなく、失敗時のリ初期化(reinitialization)は絶対的な最悪シナリオですが、最後の防衛線として重要なエラーリカバリ(error recovery)を実装することで、実行の正確性を保証し、将来の操作が成功可能であることを確保します。無効な状態は永続化されないため、単一の失敗が複数の失敗に連鎖することが防がれます。

拡張機能:wasm-bindgen ライブラリ向けの abort リ初期化

これに取り組んでいる間に、wasm-bindgen でビルドされた JS によって使用されるライブラリにとってこれが共通の問題であり、リカバリを実行可能とするためにアボートハンドラー(abort handler)をアタッチすることでも恩恵を得られることに気づきました。

しかし、Wasm を ES モジュール(ES module)としてビルドして直接インポートする場合(例:import { func } from ‘wasm-dep’)、ユーザーの JS アプリケーション内にあるすでにリンクされ初期化されたライブラリに対して func() を呼び出す際に Wasm abort が発生した場合、そのリカバリメカニズムが何であるかは明確ではありません。

厳密には Rust Workers のユースケースではありませんが、私たちのチームは Rust 基盤の Wasm ライブラリ依存関係を実行する JS ベースの Workers ユーザーもサポートしています。もし同時にこの問題を修正できれば、それは間接的に Cloudflare Workers プラットフォームにおける Wasm 利用にも恩恵をもたらすでしょう。

Wasm ライブラリのユースケースにおける自動 abort リカバリをサポートするため、wasm-bindgen に実験的なリ初期化メカニズム --reset-state-function のサポートを追加しました。これにより、生成されたバインディングの消費者が再インポートしたり再生成したりする必要なく、Rust アプリケーションが次の呼び出しに向けて内部の Wasm インスタンスを初期状態にリセットするよう効果的に要求できる関数が公開されます。古いインスタンスからのクラスインスタンスは、そのハンドルが孤立するため例外をスローしますが、その後新しいクラスを構築することができます。Wasm ライブラリを使用する JS アプリケーションはエラー状態になりますが、完全に機能停止することはありません。

この機能の完全な技術詳細と wasm-bindgen での使用方法は、新しい wasm-bindgen ガイドセクション「Wasm Bindgen: Handling Aborts」で解説されています。

Rust Wasm 例外処理エコシステムの成熟

この取り組みにおけるアップストリームへの貢献は wasm-bindgen プロジェクトで止まりませんでした。panic=unwind での Wasm ビルドにはまだ実験的な nightly Rust ターゲットが必要であるため、私たちはこれを安定版 Rust に取り込むのを支援するため、WebAssembly Exception Handling に対する Rust の Wasm サポートを前進させる作業も続けています。

WebAssembly 例外処理(WebAssembly Exception Handling)の開発において、仕様の後期段階での変更により、2つのバリエーションが生まれました。従来の例外処理(legacy exception handling)と、最終的な現代的な例外処理「exnref付き」(modern exception handling "with exnref")です。現在、Rust の WebAssembly ターゲットは依然として従来のバリエーション向けのコードをデフォルトで出力します。従来の例外処理は広くサポートされていますが、現在は非推奨となっています。

以下の JavaScript プラットフォームのリリース以降、現代的な WebAssembly 例外処理(WebAssembly Exception Handling)がサポートされています:

ランタイム

バージョン

リリース日

v8

13.8.1

2025年4月28日

workerd

v1.20250620.0

2025年6月19日

Chrome

138

2025年6月28日

Firefox

131

2024年10月1日

Safari

18.4

2025年3月31日

Node.js

25.0.0

2025年10月15日

サポートマトリックスの調査を進める中で、最大の懸念事項は Node.js 24 LTS のリリーススケジュールでした。このままでは、すべてのエコシステムが 2028年4月まで従来の WebAssembly 例外処理に縛られたままになってしまいます。

この不一致を発見した私たちは、現代的な例外処理を Node.js 24 リリースにバックポートし、さらにこのターゲットのサポートを確保するために Node.js 22 リリースラインで動作させるために必要な修正もバックポートすることができました。これにより、来年には現代的な例外処理の提案がデフォルトターゲットとなる見込みです。

今後数ヶ月にかけて、エンドユーザーにとって panic=unwind(パニックの巻き戻し)と現代的な例外処理への移行が可能な限り目立たないように、作業を進めていきます。

エコシステムに対するこれらの長期的な投資には時間がかかりますが、それによって Rust WebAssembly コミュニティ全体にとってより強固な基盤が築かれます。これらの改善に貢献できることを嬉しく思います。

Rust Workers における panic unwind の使用

Rust Workers のバージョン 0.8.0 では、ここで説明する手順に従ってビルドコマンドに追加できる新しい --panic-unwind フラグが導入されました。

このフラグを使用すると、パニックを完全に回復できるようになり、アボートリカバリ(abort recovery)は新しいアボート分類およびリカバリフックメカニズム(abort classification and recovery hook mechanism)を使用します。より安定した Rust Workers の体験を得るために、アップグレードして試すことを強く推奨します。また、次のリリースで panic=unwind をデフォルトにする予定です。panic=abort に留まるユーザーも、引き続き 0.6.0 から提供されているカスタムリカバリラッパー処理の恩恵を受け続けます。

Rust Workers の安定性へのコミット

この作業は、Rust Workers の安定版リリースに向けた継続的な取り組みの一環です。Wasm プラットフォームの基盤にあるこれらの鋭いエッジ(問題点)を根本から解決し、意味のある箇所ではエコシステムへの貢献を行うことで、私たちのプラットフォームだけでなく、Rust、JS、Wasm の全体のエコシステムにとってより強固な基盤を築いています。

Rust Workers 向けには今後の改善計画が複数あり、チームの Guy Bedford が先月 Wasm.io で開催された「Rust & JS Interoperability」の講演でプレビューした wasm-bindgen ジェネリクス(wasm-bindgen generics)や自動 bindgen(automated bindgen)を含む、これらの追加作業に関する更新情報をまもなく共有する予定です。

Cloudflare Discordの #rust-on-workers でお会いください。また、workers-rs および wasm-bindgen の GitHub プロジェクトへのフィードバックや議論、特に新規コントリビューターからの参加を心より歓迎いたします。

原文を表示

Rust Workers run on the Cloudflare Workers platform by compiling Rust to WebAssembly, but as we’ve found, WebAssembly has some sharp edges. When things go wrong with a panic or an unexpected abort, the runtime can be left in an undefined state. For users of Rust Workers, panics were historically fatal, poisoning the instance and possibly even bricking the Worker for a period of time.

While we were able to detect and mitigate these issues, there remained a small chance that a Rust Worker would unexpectedly fail and cause other requests to fail along with it. An unhandled Rust abort in a Worker affecting one request might escalate into a broader failure affecting sibling requests or even continue to affect new incoming requests. The root cause of this was in wasm-bindgen, the core project that generates the Rust-to-JavaScript bindings Rust Workers depend on, and its lack of built-in recovery semantics.

In this post, we’ll share how the latest version of Rust Workers handles comprehensive Wasm error recovery that solves this abort-induced sandbox poisoning. This work has been contributed back into wasm-bindgen as part of our collaboration within the wasm-bindgen organization formed last year. First with panic=unwind support, which ensures that a single failed request never poisons other requests, and then with abort recovery mechanisms that guarantee Rust code on Wasm can never re-execute after an abort.

Initial recovery mitigations

Our initial attempts to address reliability in this area focused on understanding and containing failures caused by Rust panics and aborts in production Rust Workers. We introduced a custom Rust panic handler that tracked failure state within a Worker and triggered full application reinitialization before handling subsequent requests. On the JavaScript side, this required wrapping the Rust-JavaScript call boundary using Proxy‑based indirection to ensure that all entrypoints were consistently encapsulated. We also made targeted modifications to the generated bindings to correctly reinitialize the WebAssembly module after a failure.

While this approach relied on custom JavaScript logic, it demonstrated that reliable recovery was achievable and eliminated the persistent failure modes we were seeing in practice. This solution was shipped by default to all workers‑rs users starting in version 0.6, and it laid the groundwork for the more general, upstreamed abort recovery mechanisms described in the sections that follow.

Implementing panic=unwind with WebAssembly Exception Handling

The abort recovery mechanisms described above ensure that a Worker can survive a failure, but they do so by reinitializing the entire application. For stateless request handlers, this is fine. But for workloads that hold meaningful state in memory, such as Durable Objects, reinitialization means losing that state entirely. A single panic in one request could wipe the in-memory state being used by other concurrent requests.

In most native Rust environments, panics can be unwound, allowing destructors to run and the program to recover without losing state. In WebAssembly, things historically looked very different. Rust compiled to Wasm via wasm32-unknown-unknown defaults to panic=abort, so a panic inside a Rust Worker would abruptly trap with an unreachable instruction and exit Wasm back to JS with a WebAssembly.RuntimeError.

To recover from panics without discarding instance state, we needed panic=unwind support for wasm32-unknown-unknown in wasm-bindgen, made possible by the WebAssembly Exception Handling proposal, which gained wide engine support in 2023.

We start by compiling with RUSTFLAGS='-Cpanic=unwind' cargo build -Zbuild-std, which rebuilds the standard library with unwind support and generates code with proper panic unwinding. For example:

struct HasDropA;

struct HasDropB;

extern "C" {

fn imported_func();

}

fn some_func() {

let a = HasDropA;

let b = HasDropB;

imported_func();

}

compiles to WebAssembly as:

try

call <imported_func>

catch_all

call <drop_b>

call <drop_a>

rethrow

end

call <drop_b>

call <drop_a>

This ensures that even if imported_func() panics, destructors still run. Similarly, std::panic::catch_unwind(|| some_func()) compiles into:

try

call <some_func>

;; set result to Ok(return value)

catch

try

call <std::panicking::catch_unwind::cleanup>

;; set result to Err(panic payload)

catch_all

call <core::panicking::cannot_unwind>

unreachable

end

end

Getting this to work end-to-end required several changes to the wasm-bindgen toolchain. The WebAssembly parser Walrus did not know how to handle try/catch instructions, so we added support for them. The descriptor interpreter also needed to be taught how to evaluate code containing exception handling blocks. At that point, the full application could be built with panic=unwind.

The final step was modifying the exports generated by wasm-bindgen to catch panics at the Rust-JavaScript boundary and surface them as JavaScript PanicError exceptions. One subtlety: Rust will catch foreign exceptions and abort when unwinding through extern "C" functions, so exports needed to be marked extern "C-unwind" to explicitly allow unwinding across the boundary. For futures, a panic rejects the JavaScript Promise with a PanicError.

Closures required special attention to ensure unwind safety was properly checked, via a new MaybeUnwindSafe trait that checks UnwindSafe only when built with panic=unwind. This quickly exposed a problem, though: many closures capture references that remain after an unwind, making them inherently unwind-unsafe. To avoid a situation where users are encouraged to incorrectly wrap closures in AssertUnwindSafe just to satisfy the compiler, we added Closure::new_aborting variants, which terminate on panic instead of unwinding in cases where unwind safety can't be guaranteed.

With panic unwinding enabled:

Panics in exported Rust functions are caught by wasm-bindgen

Panics surface to JavaScript as PanicError exceptions

Async exports reject their returned promises with a PanicError

Rust destructors run correctly

The WebAssembly instance remains valid and reusable

The full details of the approach and how to use it in wasm-bindgen are covered in the latest guide page for Wasm Bindgen: Catching Panics.

Abort recovery

Even with panic=unwind support, aborts still happen - out-of-memory errors being one common cause. Because aborts can’t unwind, there is no possibility of state recovery at all, but we can at least detect and recover from aborts for future operations to avoid invalid state erroring subsequent requests.

Panic unwind support introduced a new problem for abort recovery. When we receive an error from Wasm we don’t know if it came from an extern “C-unwind” foreign error, or if it was a genuine abort. Aborts can take many shapes in WebAssembly.

We had two options to solve this technically: either mark all errors which are definitely aborts, or mark all errors which are definitely unwinds. Either could have worked but we chose the latter. Since our foreign exception handling was directly using raw WAT-level (WebAssembly text format) Exception Handling instructions already, we found it easier to implement exception tags for foreign exceptions to distinguish them from aborting non-unwind-safe exceptions.

With the ability to clearly distinguish between recoverable and non-recoverable errors thanks to this Exception.Tag feature in WebAssembly Exception Handling, we were able to then integrate both a new abort handler as well as abort reentrancy guards.

A new abort hook, set_on_abort, can be used at initialization time to attach a handler that recovers accordingly for the platform embedding’s needs.

Hardening panic and abort handling is critical to avoiding invalid execution state. WebAssembly allows deeply interleaved call stacks, where Wasm can call into JavaScript and JavaScript can re-enter Wasm at arbitrary depths, while alongside this, multiple tasks can be functioning in the same instance. Previously, an abort occurring in one task or nested stack was not guaranteed to invalidate higher stacks through JS, leading to undefined behavior. Care was required to ensure we can guarantee the execution model, and contribution in this space remains ongoing.

While aborts are never ideal, and reinitialization on failure is an absolute worst-case scenario, implementing critical error recovery as the last line of defense ensures execution correctness and that future operations will be able to succeed. The invalid state does not persist, ensuring a single failure does not cascade into multiple failures.

Extension: abort reinitialization for wasm-bindgen libraries

While we were working on this, we realized that this is a common problem for libraries used by JS that are built with wasm-bindgen, and that they would also benefit from attaching an abort handler to be able to perform recovery.

But when building Wasm as an ES module and importing it directly (e.g. via import { func } from ‘wasm-dep’), it’s not clear what the recovery mechanism would be for a Wasm abort while calling func() for an already-linked and initialized library that is in a user JS application.

While not strictly a Rust Workers use case, our team also supports JS-based Workers users who run Rust-backed Wasm library dependencies. If we could fix this problem at the same time, that could indirectly also benefit Wasm usage on the Cloudflare Workers platform.

To support automatic abort recovery for Wasm library use cases, we added support for an experimental reinitialization mechanism into wasm‑bindgen, --reset-state-function. This exposes a function that allows the Rust application to effectively request that it reset its internal Wasm instance back to its initial state for the next call, without requiring consumers of the generated bindings to reimport or recreate them. Class instances from the old instance will throw as their handles become orphaned, but new classes can then be constructed. The JS application using a Wasm library is errored but not bricked.

The full technical details of this feature and how to use it in wasm-bindgen are covered in the new wasm-bindgen guide section Wasm Bindgen: Handling Aborts.

Maturing the Rust Wasm Exception Handling ecosystem

Upstream contributions for this work did not stop at the wasm-bindgen project. Building for Wasm with panic=unwind still requires an experimental nightly Rust target, so we’ve also been working to advance Rust’s Wasm support for WebAssembly Exception Handling to help bring this to stable Rust.

During the development of WebAssembly Exception Handling, a late‑stage specification change resulted in two variants: legacy exception handling and the final modern exception handling "with exnref". Today, Rust’s WebAssembly targets still default to emitting code for the legacy variant. While legacy exception handling is widely supported, it is now deprecated.

Modern WebAssembly Exception Handling is supported as of the following JS platform releases:

Runtime

Version

Release Date

v8

13.8.1

April 28, 2025

workerd

v1.20250620.0

June 19, 2025

Chrome

138

June 28, 2025

Firefox

131

October 1, 2024

Safari

18.4

March 31, 2025

Node.js

25.0.0

October 15, 2025

As we were investigating the support matrix, the largest concern ended up being the Node.js 24 LTS release schedule, which would have left the entire ecosystem stuck on legacy WebAssembly Exception Handling until April 2028.

Having discovered this discrepancy, we were able to backport modern exception handling to the Node.js 24 release, and even backport the fixes needed to make it work on the Node.js 22 release line to ensure support for this target. This should allow the modern Exception Handling proposal to become the default target next year.

Over the coming months, we’ll be working to make the transition to stable panic=unwind and modern Exception Handling as invisible as possible to end users.

While these long‑term investments in the ecosystem take time, they help build a stronger foundation for the Rust WebAssembly community as a whole, and we’re glad to be able to contribute to these improvements.

Using panic unwind in Rust Workers

As of version 0.8.0 of Rust Workers, we have a new --panic-unwind flag, which can be added to the build command, following the instructions here.

With this flag, panics can be fully recovered, and abort recovery will use the new abort classification and recovery hook mechanism. We highly recommend upgrading and trying it out for a more stable Rust Workers experience, and plan to make panic=unwind the default in a subsequent release. Users remaining on panic=abort will still continue to take advantage of the previous custom recovery wrapper handling from 0.6.0.

Committing to Rust Workers stability

This work is part of our ongoing effort towards a stable release for Rust Workers. By solving these sharp edges of the Wasm platform foundations at their root, and contributing back to the ecosystem where it makes sense, we build stronger foundations not just for our platform, but the entire Rust, JS, and Wasm ecosystem.

We have a number of future improvements planned for Rust Workers, and we’ll soon be sharing updates on this additional work, including wasm-bindgen generics and automated bindgen, which Guy Bedford from our team previewed in a talk on Rust & JS Interoperability at Wasm.io last month.

Find us in #rust‑on‑workers on the Cloudflare Discord. We also welcome feedback and discussion and especially all new contributors to the workers-rs and wasm-bindgen GitHub projects.

この記事をシェア

関連記事

Simon Willison Blog★32026年4月14日 00:04

新しい`servo`クレートの探求

Servoチームは、ブラウザエンジンを埋め込み可能なライブラリとしてパッケージ化した`servo`クレートの初期リリースを発表した。

Simon Willison Blog★32026年6月6日 12:53

MicroPython と WASM を用いたサンドボックス環境での Python コード実行

Simon Willison は、コード実行のサンドボックス環境を実現する新アルファパッケージ「micropython-wasm」を公開し、Datasette Agent のプラグインとして利用を開始した。

Simon Willison Blog★32026年6月3日 04:28

Datasette Agent MicroPython 0.1a0 のリリース

Simon Willison が、GPT-5.5 を使用して Python コードを安全に生成・実行する「Datasette Agent」のアルファ版「datasette-agent-micropython 0.1a0」を発表し、サンドボックスからの脱出を試みる攻撃が失敗したと報告しました。

ニュース一覧に戻る元記事を読む