Skip to content

Conversation

@scottmarchant
Copy link
Contributor

@scottmarchant scottmarchant commented Oct 22, 2025

Use fatalError in all .wait() calls for WASI builds only, and point developers towards .get() instead.

Motivation:

While working to adopt NIO in some wasm code, I've commonly ran into issues any time code calls .wait() during wasm runtime. Typically the executable either traps or crashes any time .wait() is called with an ambiguous error: Uncaught (in promise) RuntimeError: Atomics.wait cannot be called in this context. The error occurs because it is forbidden to block the main thread for a wasm executable, and the current implementation of .wait() blocks the calling thread.

The fix is straight forward, all calls to .wait() need refactor to .get(), which sometimes involves some Swift Concurrency adoption (eg. async) in the process. That change avoids blocking the main thread.

Modifications:

Added fatalError with a descriptive error message to help developers identify the issue easier.

Result:

For WASI builds only, changes the trap error message Uncaught (in promise) RuntimeError: Atomics.wait cannot be called in this context into the following error message instead:

NIO's wait() function should not be called on WASI platforms. It will freeze or crash. Use get() instead.

Alternatives considered

  • We could instead conditionalize .wait() completely out of nio for WASI builds, to turn runtime errors into compiler errors. That makes detection of this issue easier, but forces a refactor and breaking change, and somewhat precludes the possibility that WASI might support this down the road with a future change.
  • We could add a deprecation for WASI only. But long term WASI may be able to support this blocking call, so deprecation and removal is communicating the wrong message if the future ends up being reality.

Context

This PR is part of a larger effort by PassiveLogic to move Swift for WebAssembly support forward in a large number of dependencies.

@scottmarchant
Copy link
Contributor Author

@MaxDesiatov @kateinoigakukun Would love to have your thoughts on this. Open to other solutions. But from what I've experienced so far, having this change could be very helpful for developers newly adopting swift nio into their WASI builds.

@scottmarchant scottmarchant changed the title chore: Use fatalError in all .wait() calls for WASI builds only. Devs will need to use .get() instead for WASI. chore: Use fatalError in all .wait() calls for WASI builds only. Devs should use .get() instead for WASI. Oct 22, 2025
@scottmarchant scottmarchant changed the title chore: Use fatalError in all .wait() calls for WASI builds only. Devs should use .get() instead for WASI. chore: For WASI builds only, use fatalError in all .wait() calls. Use .get() instead. Oct 22, 2025
@scottmarchant scottmarchant changed the title chore: For WASI builds only, use fatalError in all .wait() calls. Use .get() instead. chore: For WASI builds only, use fatalError in all .wait() calls. Recommend using .get() instead. Oct 22, 2025
@Lukasa Lukasa added the 🔨 semver/patch No public API change. label Oct 27, 2025
…existing blocking call in wait() will cause wasm executables to trap with an ambiguous message. This improves the message to help developers understand and correct the issue.
@scottmarchant scottmarchant force-pushed the chore/improveErrorMessagingForWASIUsageOfNIO branch from 47b563d to af8a704 Compare October 28, 2025 00:52
@scottmarchant
Copy link
Contributor Author

Rebased these changes on the latest main

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔨 semver/patch No public API change.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants