use std::path::PathBuf;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum WasiError {
#[error("Invalid path '{path}': {reason}")]
InvalidPath { path: PathBuf, reason: String },
#[error("Path '{path}' escapes sandbox (resolved to '{resolved}')")]
SandboxEscape { path: PathBuf, resolved: PathBuf },
#[error("Path does not exist: {0}")]
PathNotFound(PathBuf),
#[error("Path is not a directory: {0}")]
NotADirectory(PathBuf),
#[error("Environment variable not found: {0}")]
EnvNotFound(String),
#[error("Invalid environment variable pattern: {0}")]
InvalidEnvPattern(String),
#[error("Failed to create WASI context: {0}")]
ContextCreation(String),
#[error("Failed to preopen directory '{path}': {source}")]
PreopenFailed {
path: PathBuf,
#[source]
source: std::io::Error,
},
#[error("Failed to resolve symlink '{path}': {source}")]
SymlinkResolution {
path: PathBuf,
#[source]
source: std::io::Error,
},
#[error("Working directory must be set for relative path resolution")]
WorkingDirectoryNotSet,
#[error("Capability not supported: {0}")]
UnsupportedCapability(String),
}
impl WasiError {
pub fn invalid_path(path: impl Into<PathBuf>, reason: impl Into<String>) -> Self {
Self::InvalidPath {
path: path.into(),
reason: reason.into(),
}
}
pub fn sandbox_escape(path: impl Into<PathBuf>, resolved: impl Into<PathBuf>) -> Self {
Self::SandboxEscape {
path: path.into(),
resolved: resolved.into(),
}
}
pub fn is_security_violation(&self) -> bool {
matches!(self, Self::SandboxEscape { .. } | Self::InvalidPath { .. })
}
}