zeebe_rs/job/
fail.rs

1use crate::{Client, ClientError, proto};
2use serde::Serialize;
3use std::time::Duration;
4
5pub struct Initial;
6pub struct WithKey;
7
8pub trait FailJobRequestState {}
9impl FailJobRequestState for Initial {}
10impl FailJobRequestState for WithKey {}
11
12/// Request to mark a job as failed
13///
14/// This struct uses a builder pattern with state transitions to ensure that
15/// required fields are set before sending the request. The state transitions
16/// are enforced at compile time using marker traits.
17///
18/// # Examples
19/// ```ignore
20/// client
21///     .fail_job()
22///     .with_job_key(123456)
23///     .send()
24///     .await?;
25/// ```
26#[derive(Debug, Clone)]
27pub struct FailJobRequest<T: FailJobRequestState> {
28    client: Client,
29    job_key: i64,
30    retries: i32,
31    error_message: String,
32    retry_back_off: i64,
33    variables: serde_json::Value,
34    _state: std::marker::PhantomData<T>,
35}
36
37impl<T: FailJobRequestState> FailJobRequest<T> {
38    pub(crate) fn new(client: Client) -> FailJobRequest<Initial> {
39        FailJobRequest {
40            client,
41            job_key: 0,
42            retries: 0,
43            error_message: String::new(),
44            retry_back_off: 0,
45            variables: serde_json::Value::default(),
46            _state: std::marker::PhantomData,
47        }
48    }
49
50    fn transition<NewState: FailJobRequestState>(self) -> FailJobRequest<NewState> {
51        FailJobRequest {
52            client: self.client,
53            job_key: self.job_key,
54            retries: self.retries,
55            error_message: self.error_message,
56            retry_back_off: self.retry_back_off,
57            variables: self.variables,
58            _state: std::marker::PhantomData,
59        }
60    }
61}
62
63impl FailJobRequest<Initial> {
64    /// Sets the job key to identify which job failed
65    ///
66    /// # Arguments
67    ///
68    /// * `job_key` - The unique key identifying the job
69    ///
70    /// # Returns
71    ///
72    /// A FailJobRequest in the `WithKey` state
73    pub fn with_job_key(mut self, job_key: i64) -> FailJobRequest<WithKey> {
74        self.job_key = job_key;
75        self.transition()
76    }
77}
78
79impl FailJobRequest<WithKey> {
80    /// Sets the number of remaining retries for the job
81    ///
82    /// # Arguments
83    ///
84    /// * `retries` - The number of remaining retries for the job
85    ///
86    /// # Returns
87    ///
88    /// The updated FailJobRequest
89    pub fn with_retries(mut self, retries: i32) -> Self {
90        self.retries = retries;
91        self
92    }
93
94    /// Sets an error message describing why the job failed
95    ///
96    /// # Arguments
97    ///
98    /// * `error_message` - A message describing why the job failed
99    ///
100    /// # Returns
101    ///
102    /// The updated FailJobRequest
103    pub fn with_error_message(mut self, error_message: String) -> Self {
104        self.error_message = error_message;
105        self
106    }
107
108    /// Sets the time to wait before retrying the job
109    ///
110    /// # Arguments
111    ///
112    /// * `retry_back_off` - Time to wait in seconds before retrying
113    ///
114    /// # Returns
115    ///
116    /// The updated FailJobRequest
117    pub fn with_retry_back_off(mut self, retry_back_off: Duration) -> Self {
118        self.retry_back_off = retry_back_off.as_millis() as i64;
119        self
120    }
121
122    /// Sets variables to be included with the job failure
123    ///
124    /// # Arguments
125    ///
126    /// * `data` - The variables to be included with the job failure
127    ///
128    /// # Returns
129    ///
130    /// The updated FailJobRequest or a ClientError if serialization fails
131    pub fn with_variables<T: Serialize>(mut self, data: T) -> Result<Self, ClientError> {
132        self.variables = serde_json::to_value(data)
133            .map_err(|e| ClientError::SerializationFailed { source: e })?;
134        Ok(self)
135    }
136
137    /// Sends the job failure request to the Zeebe workflow engine
138    ///
139    /// # Returns
140    ///
141    /// A Result containing a FailJobResponse if successful, or a ClientError if the request fails
142    pub async fn send(mut self) -> Result<FailJobResponse, ClientError> {
143        let res = self
144            .client
145            .gateway_client
146            .fail_job(proto::FailJobRequest {
147                job_key: self.job_key,
148                retries: self.retries,
149                error_message: self.error_message,
150                retry_back_off: self.retry_back_off,
151                variables: self.variables.to_string(),
152            })
153            .await?;
154
155        Ok(res.into_inner().into())
156    }
157}
158
159/// Response from marking a job as failed
160#[derive(Debug, Clone)]
161pub struct FailJobResponse {}
162
163impl From<proto::FailJobResponse> for FailJobResponse {
164    fn from(_value: proto::FailJobResponse) -> FailJobResponse {
165        FailJobResponse {}
166    }
167}