use miette::Diagnostic;
use std::path::PathBuf;
use thiserror::Error;
#[derive(Debug, Error, Diagnostic)]
#[non_exhaustive]
pub enum DcuError {
#[error("failed to read manifest at {path}")]
#[diagnostic(
code(dependency_check_updates::io_error),
help("make sure the file exists and is readable")
)]
Io {
path: PathBuf,
#[source]
source: std::io::Error,
},
#[error("failed to parse manifest at {path}")]
#[diagnostic(code(dependency_check_updates::parse_error))]
ManifestParse {
path: PathBuf,
detail: String,
},
#[error("registry lookup failed for package `{package}`: {detail}")]
#[diagnostic(
code(dependency_check_updates::registry_error),
help("check your internet connection, or set GITHUB_TOKEN if scanning workflows")
)]
RegistryLookup {
package: String,
detail: String,
},
#[error("failed to apply patch to {path}")]
#[diagnostic(code(dependency_check_updates::patch_error))]
PatchFailed {
path: PathBuf,
detail: String,
},
#[error("invalid semver: {input}")]
#[diagnostic(code(dependency_check_updates::semver_error))]
SemverParse {
input: String,
detail: String,
},
#[error("no manifest found in {path}")]
#[diagnostic(
code(dependency_check_updates::no_manifest),
help(
"run dependency-check-updates in a directory containing package.json, or use --manifest"
)
)]
NoManifest {
path: PathBuf,
},
}
#[cfg(test)]
mod tests {
use super::*;
use rstest::rstest;
fn io_err() -> DcuError {
DcuError::Io {
path: PathBuf::from("test.json"),
source: std::io::Error::new(std::io::ErrorKind::NotFound, "file not found"),
}
}
fn manifest_parse_err() -> DcuError {
DcuError::ManifestParse {
path: PathBuf::from("package.json"),
detail: "unexpected token".to_owned(),
}
}
fn no_manifest_err() -> DcuError {
DcuError::NoManifest {
path: PathBuf::from("/some/dir"),
}
}
fn registry_lookup_err() -> DcuError {
DcuError::RegistryLookup {
package: "lodash".to_owned(),
detail: "connection timeout".to_owned(),
}
}
fn semver_parse_err() -> DcuError {
DcuError::SemverParse {
input: "not.a.version".to_owned(),
detail: "invalid semver format".to_owned(),
}
}
#[rstest]
#[case::io(
io_err(),
format!("failed to read manifest at {}", PathBuf::from("test.json").display())
)]
#[case::manifest_parse(
manifest_parse_err(),
format!("failed to parse manifest at {}", PathBuf::from("package.json").display())
)]
#[case::no_manifest(
no_manifest_err(),
format!("no manifest found in {}", PathBuf::from("/some/dir").display())
)]
#[case::registry_lookup(
registry_lookup_err(),
"registry lookup failed for package `lodash`: connection timeout".to_owned()
)]
#[case::semver_parse(
semver_parse_err(),
"invalid semver: not.a.version".to_owned()
)]
fn dcu_error_display(#[case] err: DcuError, #[case] expected: String) {
assert_eq!(err.to_string(), expected);
}
}