qubit_executor/task/task_execution_error.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025 - 2026 Haixing Hu.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10use std::error::Error;
11use std::fmt;
12
13/// Result type used by managed task handles.
14pub type TaskResult<R, E> = Result<R, TaskExecutionError<E>>;
15
16/// Error observed when retrieving the result of an accepted task.
17///
18/// This error is distinct from [`SubmissionError`](crate::SubmissionError).
19/// Rejection happens before a service accepts a task; `TaskExecutionError`
20/// describes what happened after the task was accepted.
21///
22/// # Type Parameters
23///
24/// * `E` - The error type returned by the task itself.
25///
26#[derive(Debug)]
27pub enum TaskExecutionError<E> {
28 /// The task ran and returned `Err(E)`.
29 Failed(E),
30
31 /// The task panicked while running.
32 Panicked,
33
34 /// The task was cancelled before producing a result.
35 Cancelled,
36
37 /// The accepted runner-side completion endpoint was dropped without
38 /// publishing a result.
39 Dropped,
40}
41
42impl<E> TaskExecutionError<E> {
43 /// Returns true when this error wraps the task's own error value.
44 ///
45 /// # Returns
46 ///
47 /// `true` if the task returned `Err(E)`.
48 #[inline]
49 pub const fn is_failed(&self) -> bool {
50 matches!(self, Self::Failed(_))
51 }
52
53 /// Returns true when the task panicked.
54 ///
55 /// # Returns
56 ///
57 /// `true` if the task panicked while running.
58 #[inline]
59 pub const fn is_panicked(&self) -> bool {
60 matches!(self, Self::Panicked)
61 }
62
63 /// Returns true when the task was cancelled.
64 ///
65 /// # Returns
66 ///
67 /// `true` if the task was cancelled before producing a result.
68 #[inline]
69 pub const fn is_cancelled(&self) -> bool {
70 matches!(self, Self::Cancelled)
71 }
72
73 /// Returns true when the task result was dropped by the completion endpoint.
74 ///
75 /// # Returns
76 ///
77 /// `true` if the accepted runner-side completion endpoint disappeared
78 /// without publishing a result.
79 #[inline]
80 pub const fn is_dropped(&self) -> bool {
81 matches!(self, Self::Dropped)
82 }
83}
84
85impl<E> fmt::Display for TaskExecutionError<E>
86where
87 E: fmt::Display,
88{
89 /// Formats this task execution error for users.
90 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91 match self {
92 Self::Failed(err) => write!(f, "task failed: {err}"),
93 Self::Panicked => f.write_str("task panicked"),
94 Self::Cancelled => f.write_str("task was cancelled"),
95 Self::Dropped => f.write_str("task result was dropped"),
96 }
97 }
98}
99
100impl<E> Error for TaskExecutionError<E> where E: Error + 'static {}