Skip to content

Commit

Permalink
feat(wasmtime): add error hint for missing WASI imports
Browse files Browse the repository at this point in the history
This commit adds some code to print an error hint when a failed
`wasmtime run` command could have been called with arguments (in
particular `-S <capability>`) that would have enabled the command to succeed.

Signed-off-by: Victor Adossi <[email protected]>
  • Loading branch information
vados-cosmonic committed Feb 20, 2025
1 parent 0b4c754 commit fadc897
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 2 deletions.
12 changes: 12 additions & 0 deletions crates/cli-flags/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,18 @@ wasmtime_option_group! {
}
}

impl WasiOptions {
/// Get the name of a relevant WASI option for a given import
pub fn option_for_import(import_name: &str) -> Option<&str> {
// TODO: do we have common import parsing machinery?
if import_name.contains("wasi:http") {
return Some("http");
}
// TODO: fill out
return None;
}
}

#[derive(Debug, Clone, PartialEq)]
pub struct WasiNnGraph {
pub format: String,
Expand Down
38 changes: 36 additions & 2 deletions src/commands/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use std::sync::{Arc, Mutex};
use std::thread;
use wasi_common::sync::{ambient_authority, Dir, TcpListener, WasiCtxBuilder};
use wasmtime::{Engine, Func, Module, Store, StoreLimits, Val, ValType};
use wasmtime_cli_flags::WasiOptions;
use wasmtime_wasi::{IoView, WasiView};

#[cfg(feature = "wasi-nn")]
Expand Down Expand Up @@ -472,12 +473,20 @@ impl RunCommand {

let component = module.unwrap_component();

let command = wasmtime_wasi::bindings::Command::instantiate_async(
let command = match wasmtime_wasi::bindings::Command::instantiate_async(
&mut *store,
component,
linker,
)
.await?;
.await
{
Ok(c) => c,
Err(e) => {
print_wasi_import_option_hint(&e.to_string(), component, store);
bail!(e);
}
};

let result = command
.wasi_cli_run()
.call_run(&mut *store)
Expand Down Expand Up @@ -1026,3 +1035,28 @@ fn write_core_dump(
.with_context(|| format!("failed to write core dump file at `{path}`"))?;
Ok(())
}

/// Print a hint about wasi import options for a given error
/// message, only if it contains an error that is likely to refer
/// to a missing option (i.e. -S <wasi import>)
#[cfg(feature = "component-model")]
fn print_wasi_import_option_hint(
err_string: &str,
component: &wasmtime::component::Component,
store: &mut Store<Host>,
) {
if err_string.contains("matching implementation was not found in the linker") {
// Check if we're missing some imports that could have been provided by
for (name, _) in component.component_type().imports(store.engine()) {
if err_string.contains(&name) {
if let Some(option) = WasiOptions::option_for_import(&name) {
eprintln!(
"warning: missing import [{name}] has a WASI import option [{option}] \
that has not been enabled -- consider re-running with '-S {option}'.\n\
Run `wasmtime -S help` for a full list of WASI import options.\n",
);
}
}
}
}
}

0 comments on commit fadc897

Please sign in to comment.