pub type Result<T, E = Error> = std::result::Result<T, E>;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("service `{name}` is not registered")]
MissingService { name: &'static str },
#[error("service `{name}` is already registered in this scope")]
DuplicateService { name: &'static str },
#[error("service `{name}` was stored with an incompatible type")]
ServiceTypeMismatch { name: &'static str },
#[error("service `{name}` is owned by another activation")]
ServiceOwnership { name: &'static str },
#[error("scope `{name}` is no longer active")]
ScopeInactive { name: String },
#[error("application is shut down")]
ApplicationShutdown,
#[error("plugin is disposed")]
PluginDisposed,
#[error("plugin failed: {0}")]
PluginFailed(String),
#[error("task failed: {0}")]
TaskJoin(#[from] tokio::task::JoinError),
#[error("task did not stop within {seconds} seconds")]
TaskTimeout { seconds: u64 },
#[error("panic captured: {0}")]
Panic(String),
#[error("dependency cycle: {0}")]
DependencyCycle(String),
#[error("cleanup failed: {0}")]
Cleanup(String),
#[error(transparent)]
Other(#[from] Box<dyn std::error::Error + Send + Sync>),
}
impl Error {
pub fn cleanup(error: impl std::fmt::Display) -> Self {
Self::Cleanup(error.to_string())
}
pub(crate) fn panic(payload: Box<dyn std::any::Any + Send>) -> Self {
let message = payload
.downcast_ref::<&str>()
.map(|value| (*value).to_owned())
.or_else(|| payload.downcast_ref::<String>().cloned())
.unwrap_or_else(|| "non-string panic payload".to_owned());
Self::Panic(message)
}
}