Skip to content

Commit b42b1d1

Browse files
committed
Make error messages for missing shared libraries more useful
1 parent 0fb1089 commit b42b1d1

File tree

1 file changed

+53
-18
lines changed

1 file changed

+53
-18
lines changed

lib/wasix/src/state/linker.rs

Lines changed: 53 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -471,8 +471,8 @@ pub enum LinkError {
471471
#[error("Failed to allocate function table indices: {0}")]
472472
TableAllocationError(RuntimeError),
473473

474-
#[error("File system error: {0}")]
475-
FileSystemError(#[from] FsError),
474+
#[error("Failed to find shared library {0}: {1}")]
475+
SharedLibraryMissing(String, FsErrors),
476476

477477
#[error("Module is not a dynamic library")]
478478
NotDynamicLibrary,
@@ -519,6 +519,25 @@ pub enum LinkError {
519519
MissingTlsInitializer,
520520
}
521521

522+
#[derive(Debug)]
523+
pub enum FsErrors {
524+
SingleError(FsError),
525+
MultipleErrors(Vec<(PathBuf, FsError)>),
526+
}
527+
impl std::fmt::Display for FsErrors {
528+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
529+
match self {
530+
FsErrors::SingleError(e) => std::fmt::Display::fmt(&e, f),
531+
FsErrors::MultipleErrors(errors) => {
532+
for (path, error) in errors {
533+
write!(f, "\n {}: {}", path.display(), error)?;
534+
}
535+
Ok(())
536+
}
537+
}
538+
}
539+
}
540+
522541
#[derive(Debug)]
523542
enum PartiallyResolvedExport {
524543
Function(Function),
@@ -3566,14 +3585,25 @@ async fn locate_module(
35663585

35673586
if module_path.is_absolute() {
35683587
trace!(?module_path, "Locating module with absolute path");
3569-
Ok(try_load(&fs.root_fs, module_path).await?)
3588+
try_load(&fs.root_fs, module_path).await.map_err(|e| {
3589+
LinkError::SharedLibraryMissing(
3590+
module_path.to_string_lossy().into_owned(),
3591+
FsErrors::SingleError(e),
3592+
)
3593+
})
35703594
} else if module_path.components().count() > 1 {
35713595
trace!(?module_path, "Locating module with relative path");
3572-
Ok(try_load(
3596+
try_load(
35733597
&fs.root_fs,
35743598
fs.relative_path_to_absolute(module_path.to_string_lossy().into_owned()),
35753599
)
3576-
.await?)
3600+
.await
3601+
.map_err(|e| {
3602+
LinkError::SharedLibraryMissing(
3603+
module_path.to_string_lossy().into_owned(),
3604+
FsErrors::SingleError(e),
3605+
)
3606+
})
35773607
} else {
35783608
// Go through all dynamic library lookup paths
35793609
// Note: a path without a slash does *not* look at the current directory. This is by design.
@@ -3585,25 +3615,30 @@ async fn locate_module(
35853615
?module_path,
35863616
"Locating module by name in default runtime path"
35873617
);
3588-
3589-
if let Some(library_path) = library_path {
3590-
for path in library_path {
3591-
if let Ok(ret) = try_load(&fs.root_fs, path.as_ref().join(module_path)).await {
3618+
let search_paths = library_path
3619+
.iter()
3620+
.flat_map(|paths| paths.iter().map(AsRef::as_ref))
3621+
// Add default runtime paths
3622+
.chain(DEFAULT_RUNTIME_PATH.iter().map(|path| Path::new(path)));
3623+
3624+
let mut errors: Vec<(PathBuf, FsError)> = Vec::new();
3625+
for path in search_paths {
3626+
let full_path = path.join(module_path);
3627+
trace!(?module_path, full_path = ?full_path, "Searching module");
3628+
match try_load(&fs.root_fs, &full_path).await {
3629+
Ok(ret) => {
35923630
trace!(?module_path, full_path = ?ret.0, "Located module");
35933631
return Ok(ret);
35943632
}
3595-
}
3596-
}
3597-
3598-
for path in DEFAULT_RUNTIME_PATH {
3599-
if let Ok(ret) = try_load(&fs.root_fs, Path::new(path).join(module_path)).await {
3600-
trace!(?module_path, full_path = ?ret.0, "Located module");
3601-
return Ok(ret);
3602-
}
3633+
Err(e) => errors.push((full_path, e)),
3634+
};
36033635
}
36043636

36053637
trace!(?module_path, "Failed to locate module");
3606-
Err(FsError::EntryNotFound.into())
3638+
Err(LinkError::SharedLibraryMissing(
3639+
module_path.to_string_lossy().into_owned(),
3640+
FsErrors::MultipleErrors(errors),
3641+
))
36073642
}
36083643
}
36093644

0 commit comments

Comments
 (0)