flare_core/common/error/
localized.rs1use super::code::{ErrorCategory, ErrorCode};
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6use std::fmt;
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct LocalizedError {
11 pub code: ErrorCode,
13 pub reason: String,
15 #[serde(skip_serializing_if = "Option::is_none")]
17 pub details: Option<String>,
18 #[serde(skip_serializing_if = "Option::is_none")]
20 pub params: Option<HashMap<String, String>>,
21 #[serde(with = "chrono::serde::ts_milliseconds")]
23 pub timestamp: chrono::DateTime<chrono::Utc>,
24}
25
26impl LocalizedError {
27 pub fn new(code: ErrorCode, reason: impl Into<String>) -> Self {
29 Self {
30 code,
31 reason: reason.into(),
32 details: None,
33 params: None,
34 timestamp: chrono::Utc::now(),
35 }
36 }
37
38 #[must_use]
40 pub fn with_details(mut self, details: impl Into<String>) -> Self {
41 self.details = Some(details.into());
42 self
43 }
44
45 #[must_use]
47 pub fn with_params(mut self, params: HashMap<String, String>) -> Self {
48 self.params = Some(params);
49 self
50 }
51
52 #[must_use]
54 pub fn with_param(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
55 if self.params.is_none() {
56 self.params = Some(HashMap::new());
57 }
58 if let Some(ref mut params) = self.params {
59 params.insert(key.into(), value.into());
60 }
61 self
62 }
63
64 #[inline]
66 pub fn code_value(&self) -> u32 {
67 self.code.as_u32()
68 }
69
70 #[inline]
72 pub fn code_str(&self) -> &'static str {
73 self.code.as_str()
74 }
75
76 #[inline]
78 pub fn category(&self) -> ErrorCategory {
79 self.code.category()
80 }
81
82 #[inline]
84 pub fn is_retryable(&self) -> bool {
85 self.code.is_retryable()
86 }
87}
88
89impl fmt::Display for LocalizedError {
90 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91 write!(f, "{}: {}", self.code.as_str(), self.reason)
92 }
93}