Skip to main content

ps_promise/rejection/task_failure/
mod.rs

1mod implementations;
2
3use std::error::Error;
4use std::sync::Arc;
5
6use thiserror::Error;
7
8/// The cause of a task failure: the underlying task ended without producing
9/// a rejection value, e.g. it panicked or was cancelled.
10///
11/// Passed to
12/// [`PromiseRejection::task_failed`](crate::PromiseRejection::task_failed)
13/// so the rejection type can represent the failure.
14#[derive(Clone, Error)]
15#[non_exhaustive]
16pub enum TaskFailure {
17    /// The task was aborted, either through an
18    /// [`AbortHandle`](crate::AbortHandle) or by external cancellation of
19    /// the underlying task, such as a tokio runtime shutdown.
20    #[error("promise aborted")]
21    Aborted,
22
23    /// The task failed with an error, such as when every resolver handle
24    /// was dropped.
25    #[error(transparent)]
26    Error(Arc<dyn Error + Send + Sync + 'static>),
27
28    /// The task panicked. Carries the panic message.
29    #[error("task panicked: {0}")]
30    Panic(Arc<str>),
31
32    /// A [`Promise::timeout`](crate::Promise::timeout) deadline elapsed.
33    #[error("promise timed out")]
34    Timeout,
35}
36
37#[cfg(test)]
38mod tests {
39    use std::sync::Arc;
40
41    use super::TaskFailure;
42
43    #[test]
44    fn clone_preserves_error() {
45        let failure = TaskFailure::Error(Arc::new(std::io::Error::other("boom")));
46        let clone = failure.clone();
47
48        assert!(matches!(clone, TaskFailure::Error(_)));
49        assert_eq!(clone.to_string(), failure.to_string());
50    }
51
52    #[test]
53    fn clone_preserves_panic() {
54        let failure = TaskFailure::Panic("boom".into());
55        let clone = failure.clone();
56
57        assert!(matches!(clone, TaskFailure::Panic(_)));
58        assert_eq!(clone.to_string(), failure.to_string());
59    }
60}