diff --git a/crates/tower-runtime/src/errors.rs b/crates/tower-runtime/src/errors.rs index 75a6b09c..0b4a96fd 100644 --- a/crates/tower-runtime/src/errors.rs +++ b/crates/tower-runtime/src/errors.rs @@ -5,8 +5,8 @@ pub enum Error { #[snafu(display("failed to RPC server"))] RuntimeStartFailed, - #[snafu(display("spawning process"))] - SpawnFailed, + #[snafu(display("spawning process: {detail}"))] + SpawnFailed { detail: String }, #[snafu(display("no app running"))] NoRunningApp, @@ -23,8 +23,8 @@ pub enum Error { #[snafu(display("package create failed"))] PackageCreateFailed, - #[snafu(display("package unpack failed"))] - PackageUnpackFailed, + #[snafu(display("package unpack failed: {detail}"))] + PackageUnpackFailed { detail: String }, #[snafu(display("container already initialized"))] AlreadyInitialized, @@ -79,8 +79,10 @@ pub enum Error { } impl From for Error { - fn from(_: std::io::Error) -> Self { - Error::SpawnFailed + fn from(err: std::io::Error) -> Self { + Error::SpawnFailed { + detail: err.to_string(), + } } } @@ -93,19 +95,18 @@ impl From for Error { impl From for Error { fn from(err: tower_uv::Error) -> Self { match err { - tower_uv::Error::IoError(_) => Error::SpawnFailed, - tower_uv::Error::NotFound(_) => Error::SpawnFailed, - tower_uv::Error::PermissionDenied(_) => Error::SpawnFailed, - tower_uv::Error::Other(_) => Error::SpawnFailed, - tower_uv::Error::MissingPyprojectToml => Error::SpawnFailed, - tower_uv::Error::InvalidUv => Error::SpawnFailed, tower_uv::Error::UnsupportedPlatform => Error::UnsupportedPlatform, + other => Error::SpawnFailed { + detail: other.to_string(), + }, } } } impl From for Error { - fn from(_: tower_package::Error) -> Self { - Error::PackageUnpackFailed + fn from(err: tower_package::Error) -> Self { + Error::PackageUnpackFailed { + detail: err.to_string(), + } } } diff --git a/crates/tower-runtime/src/subprocess.rs b/crates/tower-runtime/src/subprocess.rs index 23c7d4ef..2816dc8c 100644 --- a/crates/tower-runtime/src/subprocess.rs +++ b/crates/tower-runtime/src/subprocess.rs @@ -81,7 +81,9 @@ impl SubprocessBackend { package.tmp_dir = Some(temp_dir); package.unpack().await.map_err(|e| { error!(ctx: ctx, "Failed to unpack package: {:?}", e); - Error::PackageUnpackFailed + Error::PackageUnpackFailed { + detail: format!("{:?}", e), + } })?; info!(ctx: ctx, "Successfully unpacked package"); @@ -124,7 +126,9 @@ impl ExecutionBackend for SubprocessBackend { let unpacked_path = package .unpacked_path .clone() - .ok_or(Error::PackageUnpackFailed)?; + .ok_or(Error::PackageUnpackFailed { + detail: "no unpacked_path after unpack".to_string(), + })?; // Extract tmp_dir from package for cleanup tracking // We need to keep this alive until execution completes diff --git a/crates/tower-uv/src/lib.rs b/crates/tower-uv/src/lib.rs index 203fddab..de35cedc 100644 --- a/crates/tower-uv/src/lib.rs +++ b/crates/tower-uv/src/lib.rs @@ -26,6 +26,20 @@ pub enum Error { UnsupportedPlatform, } +impl std::fmt::Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Error::IoError(e) => write!(f, "IO error: {}", e), + Error::NotFound(msg) => write!(f, "not found: {}", msg), + Error::PermissionDenied(msg) => write!(f, "permission denied: {}", msg), + Error::Other(msg) => write!(f, "{}", msg), + Error::MissingPyprojectToml => write!(f, "missing pyproject.toml"), + Error::InvalidUv => write!(f, "invalid uv installation"), + Error::UnsupportedPlatform => write!(f, "unsupported platform"), + } + } +} + impl From for Error { fn from(err: std::io::Error) -> Self { // Convert std::fs::Error to your custom Error type