1use serde::Serialize;
7use serde_json::Value;
8use std::panic::{UnwindSafe, catch_unwind};
9
10#[derive(Debug, Clone, Serialize)]
12pub struct StructuredError {
13 pub error: String,
14 pub code: String,
15 #[serde(default)]
16 pub details: Value,
17}
18
19impl StructuredError {
20 pub fn new(code: impl Into<String>, error: impl Into<String>, details: Value) -> Self {
21 Self {
22 code: code.into(),
23 error: error.into(),
24 details,
25 }
26 }
27
28 pub fn simple(code: impl Into<String>, error: impl Into<String>) -> Self {
29 Self::new(code, error, Value::Object(serde_json::Map::new()))
30 }
31}
32
33pub fn shield_panic<T, F>(f: F) -> Result<T, StructuredError>
35where
36 F: FnOnce() -> T + UnwindSafe,
37{
38 catch_unwind(f).map_err(|_| StructuredError::simple("panic", "Unexpected panic in Rust code"))
39}