temporalio_client/
errors.rs1use http::uri::InvalidUri;
4use temporalio_common::{
5 data_converters::PayloadConversionError,
6 protos::temporal::api::{common::v1::Payload, failure::v1::Failure, query::v1::QueryRejected},
7};
8use tonic::Code;
9
10#[derive(thiserror::Error, Debug)]
12#[non_exhaustive]
13pub enum ClientConnectError {
14 #[error("Invalid URI: {0:?}")]
16 InvalidUri(#[from] InvalidUri),
17 #[error("Invalid headers: {0}")]
19 InvalidHeaders(#[from] InvalidHeaderError),
20 #[error("Server connection error: {0:?}")]
22 TonicTransportError(#[from] tonic::transport::Error),
23 #[error("`get_system_info` call error after connection: {0:?}")]
26 SystemInfoCallError(tonic::Status),
27 #[error("DNS resolution error for '{host}': {source}")]
29 DnsResolutionError {
30 host: String,
32 #[source]
34 source: std::io::Error,
35 },
36 #[error("Invalid client configuration: {0}")]
38 InvalidConfig(String),
39}
40
41#[derive(thiserror::Error, Debug)]
43#[non_exhaustive]
44pub enum InvalidHeaderError {
45 #[error("Invalid binary header key '{key}': {source}")]
47 InvalidBinaryHeaderKey {
48 key: String,
50 source: tonic::metadata::errors::InvalidMetadataKey,
52 },
53 #[error("Invalid ASCII header key '{key}': {source}")]
55 InvalidAsciiHeaderKey {
56 key: String,
58 source: tonic::metadata::errors::InvalidMetadataKey,
60 },
61 #[error("Invalid ASCII header value for key '{key}': {source}")]
63 InvalidAsciiHeaderValue {
64 key: String,
66 value: String,
68 source: tonic::metadata::errors::InvalidMetadataValue,
70 },
71}
72
73#[derive(thiserror::Error, Debug)]
75#[non_exhaustive]
76pub enum WorkflowStartError {
77 #[error("Workflow already started with run ID: {run_id:?}")]
79 AlreadyStarted {
80 run_id: Option<String>,
82 #[source]
84 source: tonic::Status,
85 },
86 #[error("Failed to serialize workflow input: {0}")]
88 PayloadConversion(#[from] PayloadConversionError),
89 #[error("Server error: {0}")]
91 Rpc(#[from] tonic::Status),
92}
93
94#[derive(Debug, thiserror::Error)]
96#[non_exhaustive]
97pub enum WorkflowQueryError {
98 #[error("Workflow not found")]
100 NotFound(#[source] tonic::Status),
101
102 #[error("Query rejected: workflow status {:?}", .0.status)]
104 Rejected(QueryRejected),
105
106 #[error("Payload conversion error: {0}")]
108 PayloadConversion(#[from] PayloadConversionError),
109
110 #[error("Server error: {0}")]
112 Rpc(tonic::Status),
113
114 #[error(transparent)]
116 Other(#[from] Box<dyn std::error::Error + Send + Sync>),
117}
118
119impl WorkflowQueryError {
120 pub(crate) fn from_status(status: tonic::Status) -> Self {
121 if status.code() == Code::NotFound {
122 Self::NotFound(status)
123 } else {
124 Self::Rpc(status)
125 }
126 }
127}
128
129#[derive(Debug, thiserror::Error)]
131#[non_exhaustive]
132pub enum WorkflowUpdateError {
133 #[error("Workflow not found")]
135 NotFound(#[source] tonic::Status),
136
137 #[error("Update failed: {0:?}")]
139 Failed(Box<Failure>),
140
141 #[error("Payload conversion error: {0}")]
143 PayloadConversion(#[from] PayloadConversionError),
144
145 #[error("Server error: {0}")]
147 Rpc(tonic::Status),
148
149 #[error(transparent)]
151 Other(#[from] Box<dyn std::error::Error + Send + Sync>),
152}
153
154impl WorkflowUpdateError {
155 pub(crate) fn from_status(status: tonic::Status) -> Self {
156 if status.code() == Code::NotFound {
157 Self::NotFound(status)
158 } else {
159 Self::Rpc(status)
160 }
161 }
162}
163
164#[derive(Debug, thiserror::Error)]
166#[non_exhaustive]
167pub enum WorkflowGetResultError {
168 #[error("Workflow failed: {0:?}")]
170 Failed(Box<Failure>),
171
172 #[error("Workflow cancelled")]
174 Cancelled {
175 details: Vec<Payload>,
177 },
178
179 #[error("Workflow terminated")]
181 Terminated {
182 details: Vec<Payload>,
184 },
185
186 #[error("Workflow timed out")]
188 TimedOut,
189
190 #[error("Workflow continued as new")]
192 ContinuedAsNew,
193
194 #[error("Workflow not found")]
196 NotFound(#[source] tonic::Status),
197
198 #[error("Payload conversion error: {0}")]
200 PayloadConversion(#[from] PayloadConversionError),
201
202 #[error("Server error: {0}")]
204 Rpc(tonic::Status),
205
206 #[error(transparent)]
208 Other(#[from] Box<dyn std::error::Error + Send + Sync>),
209}
210
211impl From<WorkflowInteractionError> for WorkflowGetResultError {
212 fn from(err: WorkflowInteractionError) -> Self {
213 match err {
214 WorkflowInteractionError::NotFound(s) => Self::NotFound(s),
215 WorkflowInteractionError::PayloadConversion(e) => Self::PayloadConversion(e),
216 WorkflowInteractionError::Rpc(s) => Self::Rpc(s),
217 WorkflowInteractionError::Other(e) => Self::Other(e),
218 }
219 }
220}
221
222impl WorkflowGetResultError {
223 pub fn is_workflow_outcome(&self) -> bool {
227 matches!(
228 self,
229 Self::Failed(_)
230 | Self::Cancelled { .. }
231 | Self::Terminated { .. }
232 | Self::TimedOut
233 | Self::ContinuedAsNew
234 )
235 }
236}
237
238#[derive(thiserror::Error, Debug)]
240#[non_exhaustive]
241pub enum ClientError {
242 #[error("Server error: {0}")]
244 Rpc(#[from] tonic::Status),
245}
246
247#[derive(Debug, thiserror::Error)]
250#[non_exhaustive]
251pub enum WorkflowInteractionError {
252 #[error("Workflow not found")]
254 NotFound(#[source] tonic::Status),
255
256 #[error("Payload conversion error: {0}")]
258 PayloadConversion(#[from] PayloadConversionError),
259
260 #[error("Server error: {0}")]
262 Rpc(tonic::Status),
263
264 #[error(transparent)]
266 Other(#[from] Box<dyn std::error::Error + Send + Sync>),
267}
268
269impl WorkflowInteractionError {
270 pub(crate) fn from_status(status: tonic::Status) -> Self {
271 if status.code() == Code::NotFound {
272 Self::NotFound(status)
273 } else {
274 Self::Rpc(status)
275 }
276 }
277}
278
279#[derive(Debug, thiserror::Error)]
281#[non_exhaustive]
282pub enum AsyncActivityError {
283 #[error("Activity not found")]
285 NotFound(#[source] tonic::Status),
286 #[error("Server error: {0}")]
288 Rpc(#[from] tonic::Status),
289}
290
291impl AsyncActivityError {
292 pub(crate) fn from_status(status: tonic::Status) -> Self {
293 if status.code() == Code::NotFound {
294 Self::NotFound(status)
295 } else {
296 Self::Rpc(status)
297 }
298 }
299}
300
301#[derive(Debug, thiserror::Error)]
305#[non_exhaustive]
306pub enum ClientNewError {}