temporal_sdk_core/
errors.rs

1use crate::{
2    protos::coresdk::activity_result::ActivityResult,
3    protos::coresdk::workflow_completion::WfActivationCompletion,
4    protos::temporal::api::workflowservice::v1::PollWorkflowTaskQueueResponse,
5    workflow::WorkflowError,
6};
7use tonic::codegen::http::uri::InvalidUri;
8
9pub(crate) struct ShutdownErr;
10pub(crate) struct WorkflowUpdateError {
11    /// Underlying workflow error
12    pub source: WorkflowError,
13    /// The run id of the erring workflow
14    pub run_id: String,
15}
16
17/// Errors thrown during initialization of [crate::Core]
18#[derive(thiserror::Error, Debug)]
19pub enum CoreInitError {
20    /// Invalid URI. Configuration error, fatal.
21    #[error("Invalid URI: {0:?}")]
22    InvalidUri(#[from] InvalidUri),
23    /// Server connection error. Crashing and restarting the worker is likely best.
24    #[error("Server connection error: {0:?}")]
25    TonicTransportError(#[from] tonic::transport::Error),
26}
27
28/// Errors thrown by [crate::Core::poll_workflow_task]
29#[derive(thiserror::Error, Debug)]
30pub enum PollWfError {
31    /// There was an error specific to a workflow instance. The cached workflow should be deleted
32    /// from lang side.
33    #[error("There was an error with the workflow instance with run id ({run_id}): {source:?}")]
34    WorkflowUpdateError {
35        /// Underlying workflow error
36        source: WorkflowError,
37        /// The run id of the erring workflow
38        run_id: String,
39    },
40    /// The server returned a malformed polling response. Either we aren't handling a valid form,
41    /// or the server is bugging out. Likely fatal.
42    #[error("Poll workflow response from server was malformed: {0:?}")]
43    BadPollResponseFromServer(PollWorkflowTaskQueueResponse),
44    /// [crate::Core::shutdown] was called, and there are no more replay tasks to be handled. Lang
45    /// must call [crate::Core::complete_workflow_task] for any remaining tasks, and then may
46    /// exit.
47    #[error("Core is shut down and there are no more workflow replay tasks")]
48    ShutDown,
49    /// Unhandled error when calling the temporal server. Core will attempt to retry any non-fatal
50    /// errors, so lang should consider this fatal.
51    #[error("Unhandled error when calling the temporal server: {0:?}")]
52    TonicError(#[from] tonic::Status),
53}
54
55impl From<WorkflowUpdateError> for PollWfError {
56    fn from(e: WorkflowUpdateError) -> Self {
57        Self::WorkflowUpdateError {
58            source: e.source,
59            run_id: e.run_id,
60        }
61    }
62}
63
64impl From<ShutdownErr> for PollWfError {
65    fn from(_: ShutdownErr) -> Self {
66        Self::ShutDown
67    }
68}
69
70/// Errors thrown by [crate::Core::poll_activity_task]
71#[derive(thiserror::Error, Debug)]
72pub enum PollActivityError {
73    /// [crate::Core::shutdown] was called, we will no longer fetch new activity tasks. Lang must
74    /// ensure it is finished with any workflow replay, see [PollWfError::ShutDown]
75    #[error("Core is shut down")]
76    ShutDown,
77    /// Unhandled error when calling the temporal server. Core will attempt to retry any non-fatal
78    /// errors, so lang should consider this fatal.
79    #[error("Unhandled error when calling the temporal server: {0:?}")]
80    TonicError(#[from] tonic::Status),
81}
82
83impl From<ShutdownErr> for PollActivityError {
84    fn from(_: ShutdownErr) -> Self {
85        Self::ShutDown
86    }
87}
88
89/// Errors thrown by [crate::Core::complete_workflow_task]
90#[derive(thiserror::Error, Debug)]
91#[allow(clippy::large_enum_variant)]
92pub enum CompleteWfError {
93    /// Lang SDK sent us a malformed workflow completion. This likely means a bug in the lang sdk.
94    #[error("Lang SDK sent us a malformed workflow completion ({reason}): {completion:?}")]
95    MalformedWorkflowCompletion {
96        /// Reason the completion was malformed
97        reason: String,
98        /// The completion, which may not be included to avoid unnecessary copies.
99        completion: Option<WfActivationCompletion>,
100    },
101    /// There was an error specific to a workflow instance. The cached workflow should be deleted
102    /// from lang side.
103    #[error("There was an error with the workflow instance with run id ({run_id}): {source:?}")]
104    WorkflowUpdateError {
105        /// Underlying workflow error
106        source: WorkflowError,
107        /// The run id of the erring workflow
108        run_id: String,
109    },
110    /// There exists a pending command in this workflow's history which has not yet been handled.
111    /// When thrown from [crate::Core::complete_workflow_task], it means you should poll for a new
112    /// task, receive a new task token, and complete that new task.
113    #[error("Unhandled command when completing workflow activation")]
114    UnhandledCommandWhenCompleting,
115    /// Unhandled error when calling the temporal server. Core will attempt to retry any non-fatal
116    /// errors, so lang should consider this fatal.
117    #[error("Unhandled error when calling the temporal server: {0:?}")]
118    TonicError(#[from] tonic::Status),
119}
120
121impl From<WorkflowUpdateError> for CompleteWfError {
122    fn from(e: WorkflowUpdateError) -> Self {
123        Self::WorkflowUpdateError {
124            source: e.source,
125            run_id: e.run_id,
126        }
127    }
128}
129
130/// Errors thrown by [crate::Core::complete_activity_task]
131#[derive(thiserror::Error, Debug)]
132pub enum CompleteActivityError {
133    /// Lang SDK sent us a malformed activity completion. This likely means a bug in the lang sdk.
134    #[error("Lang SDK sent us a malformed activity completion ({reason}): {completion:?}")]
135    MalformedActivityCompletion {
136        /// Reason the completion was malformed
137        reason: String,
138        /// The completion, which may not be included to avoid unnecessary copies.
139        completion: Option<ActivityResult>,
140    },
141    /// Unhandled error when calling the temporal server. Core will attempt to retry any non-fatal
142    /// errors, so lang should consider this fatal.
143    #[error("Unhandled error when calling the temporal server: {0:?}")]
144    TonicError(#[from] tonic::Status),
145}
146
147/// Errors thrown by [crate::Core::record_activity_heartbeat] and [crate::Core::get_last_activity_heartbeat]
148#[derive(thiserror::Error, Debug)]
149pub enum ActivityHeartbeatError {
150    #[error("Heartbeat request must contain heartbeat timeout.")]
151    HeartbeatTimeoutNotSet,
152    #[error("Heartbeat request must contain valid heartbeat timeout.")]
153    InvalidHeartbeatTimeout,
154    #[error("New heartbeat requests are not accepted while shutting down")]
155    ShuttingDown,
156    #[error("Unable to dispatch heartbeat.")]
157    SendError,
158}