Skip to content

Add experimental "no-panic" feature. #319

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

PiotrSikora
Copy link
Member

When enabled, any "this should never happen" errors in dispatcher
and/or hostcalls will be logged, but the processing will continue
as if nothing happened, instead of panicking and trapping WasmVM.

Note that any execution past the "should have panicked" point
is mostly undefined, since the state of any objects might get
out-of-sync with the host when errors and/or events are being
ignored.

When enabled, any "this should never happen" errors in dispatcher
and/or hostcalls will be logged, but the processing will continue
as if nothing happened, instead of panicking and trapping WasmVM.

Note that any execution past the "should have panicked" point
is undefined, since the state of contexts can get out-of-sync
with the host when errors and/or events are being ignored.

Signed-off-by: Piotr Sikora <code@piotrsikora.dev>
@@ -14,6 +14,10 @@ build = "build.rs"
hashbrown = "0.15"
log = "0.4"

[features]
default = []
no-panic = []
Copy link
Member Author

@PiotrSikora PiotrSikora Jun 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: This will depend on the strict-header-value (#287) once that PR is merged in order to eliminate UTF-8 panics in HTTP field values (as of now, that PR doesn't change the type of field names, but all valid HTTP field name characters are also valid UTF-8 characters).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexsnaps does this sound reasonable to you?

return;
}
};

if let Some(http_stream) = self.http_streams.borrow_mut().get_mut(&context_id) {
self.active_id.set(context_id);
hostcalls::set_effective_context(context_id).unwrap();
hostcalls::set_effective_context(context_id).unwrap_or(());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be useful to log the fact that the hostcall failed--I see that the maybe_panic in set_effective_context will do that for unexpected return values, but IIUC the BadArgument failure case will get swallowed silently. WDYT about changing these to unwrap_or_else with a closure that logs, or if that is too bulky syntax-wise, adding an internal utility function that does the same?

Copy link
Member Author

@PiotrSikora PiotrSikora Jun 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!

I have the other part of this change in my local tree, that simply removes the BadArgument case from hostcalls::set_effective_context and hostcalls::get_metric, but I went down the rabbit hole investigating the BadArgument cases (which is quite overloaded in the current ABI) and invalid context ID handling (dispatcher always panics, when it's coming from the host) across the SDK and ABI, and I didn't submit it yet.

But technically, it's a public interface, so perhaps gating unwrap_or() change on #[cfg(feature = "no-panic")] and leaving the default as-is, is the way to go, although it adds more complexity than I'd like.

Thoughts?

#[cfg(feature = "no-panic")]
#[macro_export]
macro_rules! maybe_panic {
($($arg:tt)*) => { $crate::hostcalls::log(LogLevel::Critical, format!($($arg)*).as_str()).unwrap_or(()) };
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: use log_noresult from #320 once it's merged.


#[macro_export]
macro_rules! dont_panic {
($($arg:tt)*) => { $crate::hostcalls::log(LogLevel::Critical, format!($($arg)*).as_str()).unwrap_or(()) };
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: use log_noresult from #320 once it's merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants