use std::path::PathBuf;
#[derive(thiserror::Error, Debug)]
pub enum ToolchainError {
#[error("failed to spawn the gleam binary at `{gleam_path}`: {source}")]
GleamSpawn {
gleam_path: PathBuf,
source: std::io::Error,
},
#[error("gleam compilation failed:\n{diagnostics}")]
TypeCheck {
diagnostics: String,
},
#[error(
"gleam could not reach its package registry, so the submitted source was never compiled \
— this is an infrastructure failure, not a defect in the source:\n{diagnostics}"
)]
DependencyLayer {
diagnostics: String,
},
#[error(transparent)]
Packaging(#[from] aion_package::PackagingError),
#[error("filesystem operation on `{path}` failed: {source}")]
Io {
path: PathBuf,
source: std::io::Error,
},
#[error("invalid authoring project: {message}")]
InvalidProject {
message: String,
},
}
#[cfg(test)]
mod tests {
use std::path::PathBuf;
use super::ToolchainError;
fn assert_send_sync<T: Send + Sync + 'static>() {}
#[test]
fn toolchain_error_is_send_sync_and_static() {
assert_send_sync::<ToolchainError>();
}
#[test]
fn type_check_message_carries_the_diagnostics_verbatim() {
let error = ToolchainError::TypeCheck {
diagnostics: "error: Type mismatch\n expected Int, got String".to_owned(),
};
let rendered = error.to_string();
assert!(rendered.contains("Type mismatch"));
assert!(rendered.contains("expected Int, got String"));
}
#[test]
fn spawn_message_names_the_binary_path() {
let error = ToolchainError::GleamSpawn {
gleam_path: PathBuf::from("/usr/local/bin/gleam"),
source: std::io::Error::from(std::io::ErrorKind::NotFound),
};
assert!(error.to_string().contains("/usr/local/bin/gleam"));
assert!(std::error::Error::source(&error).is_some());
}
#[test]
fn io_message_names_the_path() {
let error = ToolchainError::Io {
path: PathBuf::from("/work/src/demo.gleam"),
source: std::io::Error::from(std::io::ErrorKind::PermissionDenied),
};
assert!(error.to_string().contains("/work/src/demo.gleam"));
assert!(std::error::Error::source(&error).is_some());
}
#[test]
fn packaging_error_converts_transparently() {
let error = ToolchainError::from(aion_package::PackagingError::ConfigMissing {
root: PathBuf::from("/work"),
});
assert_eq!(error.to_string(), "no workflow.toml found in /work");
assert!(matches!(error, ToolchainError::Packaging(_)));
}
}