1pub type Result<T, E = Error> = std::result::Result<T, E>;
3
4#[derive(Debug, thiserror::Error)]
5pub enum Error {
6 #[error("service `{name}` is not registered")]
7 MissingService { name: &'static str },
8
9 #[error("service `{name}` is already registered in this scope")]
10 DuplicateService { name: &'static str },
11
12 #[error("service `{name}` was stored with an incompatible type")]
13 ServiceTypeMismatch { name: &'static str },
14
15 #[error("service `{name}` is owned by another activation")]
16 ServiceOwnership { name: &'static str },
17
18 #[error("scope `{name}` is no longer active")]
19 ScopeInactive { name: String },
20
21 #[error("application is shut down")]
22 ApplicationShutdown,
23
24 #[error("plugin is disposed")]
25 PluginDisposed,
26
27 #[error("plugin failed: {0}")]
28 PluginFailed(String),
29
30 #[error("task failed: {0}")]
31 TaskJoin(#[from] tokio::task::JoinError),
32
33 #[error("task did not stop within {seconds} seconds")]
34 TaskTimeout { seconds: u64 },
35
36 #[error("panic captured: {0}")]
37 Panic(String),
38
39 #[error("dependency cycle: {0}")]
40 DependencyCycle(String),
41
42 #[error("cleanup failed: {0}")]
43 Cleanup(String),
44
45 #[error(transparent)]
46 Other(#[from] Box<dyn std::error::Error + Send + Sync>),
47}
48
49impl Error {
50 pub fn cleanup(error: impl std::fmt::Display) -> Self {
51 Self::Cleanup(error.to_string())
52 }
53
54 pub(crate) fn panic(payload: Box<dyn std::any::Any + Send>) -> Self {
55 let message = payload
56 .downcast_ref::<&str>()
57 .map(|value| (*value).to_owned())
58 .or_else(|| payload.downcast_ref::<String>().cloned())
59 .unwrap_or_else(|| "non-string panic payload".to_owned());
60 Self::Panic(message)
61 }
62}