feat(error): type the public library API with ecr::Error

anyhow at the public boundary left library consumers unable to match
on failure modes: every mistake was an opaque error, and the ones
worth branching on (host prerequisites, unsupported architectures)
could only be recognized by string matching.

Public functions now return Result<T, ecr::Error> (thiserror) with
semantic variants for those conditions: user namespaces unavailable,
binfmt_misc unregistered, architecture not served by the registry,
missing subuid/subgid entry.  anyhow stays the internal error type;
everything else converts to Error::Other, which transparently wraps
the full context chain.  Errors raised inside the namespace child
cross the process boundary as formatted chains and also surface as
Other; the error pipe wraps them in anyhow before formatting so the
chain still survives.  The CLI maps the error back into anyhow, so
its output is unchanged.
This commit is contained in:
2026-10-04 21:20:51 +02:00
parent 2225c33ef2
commit 593ce20f4f
18 changed files with 299 additions and 171 deletions
+2 -2
View File
@@ -96,7 +96,7 @@ fn main() -> Result<()> {
log::debug!("Cleanup complete.");
}
result
result.map_err(anyhow::Error::from)
} else {
// Namespace/chroot mode
let exit_code = namespace_mode(&args, rootfs.dir(), &config, &arch)?;
@@ -122,7 +122,7 @@ fn namespace_mode(args: &Args, rootfs: &Path, config: &Config, arch: &str) -> Re
working_dir,
};
let exit_code = ecr::exec(rootfs, &opts);
let exit_code = ecr::exec(rootfs, &opts).map_err(anyhow::Error::from);
// Cleanup happens automatically via tempfile
if exit_code.is_ok() {