Skip to main content

dapr_durabletask/api/
failure_details.rs

1use crate::proto;
2
3/// Details about a task or orchestration failure.
4#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
5pub struct FailureDetails {
6    pub message: String,
7    pub error_type: String,
8    pub stack_trace: Option<String>,
9}
10
11impl From<&proto::TaskFailureDetails> for FailureDetails {
12    fn from(details: &proto::TaskFailureDetails) -> Self {
13        Self {
14            message: details.error_message.clone(),
15            error_type: details.error_type.clone(),
16            stack_trace: details.stack_trace.clone(),
17        }
18    }
19}
20
21#[cfg(test)]
22mod tests {
23    use super::*;
24
25    #[test]
26    fn from_proto_all_fields() {
27        let proto_details = proto::TaskFailureDetails {
28            error_type: "RuntimeError".into(),
29            error_message: "something broke".into(),
30            stack_trace: Some("at main.rs:42".into()),
31            inner_failure: None,
32            is_non_retriable: false,
33        };
34        let fd = FailureDetails::from(&proto_details);
35        assert_eq!(fd.message, "something broke");
36        assert_eq!(fd.error_type, "RuntimeError");
37        assert_eq!(fd.stack_trace.as_deref(), Some("at main.rs:42"));
38    }
39
40    #[test]
41    fn from_proto_no_stack_trace() {
42        let proto_details = proto::TaskFailureDetails {
43            error_type: "Error".into(),
44            error_message: "msg".into(),
45            stack_trace: None,
46            inner_failure: None,
47            is_non_retriable: true,
48        };
49        let fd = FailureDetails::from(&proto_details);
50        assert_eq!(fd.message, "msg");
51        assert_eq!(fd.error_type, "Error");
52        assert!(fd.stack_trace.is_none());
53    }
54}