kroki_rs/interface/
errors.rs1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Serialize, Deserialize, Clone)]
6pub struct ProblemDetails {
7 #[serde(rename = "type")]
9 pub problem_type: String,
10
11 pub title: String,
13
14 pub status: u16,
16
17 #[serde(skip_serializing_if = "Option::is_none")]
19 pub detail: Option<String>,
20
21 #[serde(skip_serializing_if = "Option::is_none")]
23 pub instance: Option<String>,
24}
25
26impl ProblemDetails {
27 pub fn new(problem_type: &str, title: &str, status: u16) -> Self {
28 Self {
29 problem_type: problem_type.to_string(),
30 title: title.to_string(),
31 status,
32 detail: None,
33 instance: None,
34 }
35 }
36
37 pub fn with_detail(mut self, detail: &str) -> Self {
38 self.detail = Some(detail.to_string());
39 self
40 }
41}
42
43impl From<crate::diagrams::error::DiagramError> for ProblemDetails {
44 fn from(err: crate::diagrams::error::DiagramError) -> Self {
45 use crate::diagrams::error::DiagramError::*;
46
47 let (status, problem_type, title) = match &err {
48 ValidationFailed(_) => (400, "validation-failed", "Input Validation Failed"),
49 DecodeFailed(_) => (400, "decode-failed", "Input Decoding Failed"),
50 UnsupportedFormat { .. } => (400, "unsupported-format", "Unsupported Format"),
51 ToolNotFound(_) => (503, "tool-not-found", "Rendering Tool Missing"),
52 ExecutionTimeout { .. } => (504, "execution-timeout", "Rendering Timed Out"),
53 ProcessFailed(_) | Io(_) | Internal(_) => {
54 (500, "internal-error", "Internal Server Error")
55 }
56 };
57
58 Self::new(
59 &format!("https://kroki.io/errors/{}", problem_type),
60 title,
61 status,
62 )
63 .with_detail(&err.to_string())
64 }
65}