ya_runtime_sdk/
error.rs

1use futures::future::LocalBoxFuture;
2use futures::FutureExt;
3use serde::Serialize;
4use std::collections::HashMap;
5use std::io;
6
7use crate::ErrorResponse;
8
9pub trait ErrorExt<T> {
10    fn or_err(self, s: impl ToString) -> Result<T, Error>;
11}
12
13impl<T> ErrorExt<T> for Option<T> {
14    fn or_err(self, s: impl ToString) -> Result<T, Error> {
15        match self {
16            Some(t) => Ok(t),
17            None => Err(Error::from(s.to_string())),
18        }
19    }
20}
21
22impl<T, E> ErrorExt<T> for Result<T, E>
23where
24    E: Into<Error> + std::fmt::Display,
25{
26    fn or_err(self, s: impl ToString) -> Result<T, Error> {
27        match self {
28            Ok(t) => Ok(t),
29            Err(e) => Err(Error::from(format!("{}: {}", s.to_string(), e))),
30        }
31    }
32}
33
34#[derive(Clone, Debug, Serialize)]
35pub struct Error {
36    code: i32,
37    message: String,
38    context: HashMap<String, String>,
39}
40
41impl Error {
42    pub fn response<'a, T: 'a>(s: impl ToString) -> LocalBoxFuture<'a, Result<T, Self>> {
43        let err = Self::from(s.to_string());
44        futures::future::err(err).boxed_local()
45    }
46
47    pub fn from_string(s: impl ToString) -> Self {
48        Self::from(s.to_string())
49    }
50}
51
52impl From<String> for Error {
53    fn from(message: String) -> Self {
54        Error {
55            code: 1,
56            message,
57            context: Default::default(),
58        }
59    }
60}
61
62impl From<io::Error> for Error {
63    fn from(e: io::Error) -> Self {
64        Error {
65            code: e.raw_os_error().unwrap_or(1),
66            message: e.to_string(),
67            context: Default::default(),
68        }
69    }
70}
71
72impl From<anyhow::Error> for Error {
73    fn from(e: anyhow::Error) -> Self {
74        Self::from_string(e)
75    }
76}
77
78impl From<ErrorResponse> for Error {
79    fn from(e: ErrorResponse) -> Self {
80        Error {
81            code: e.code,
82            message: e.message,
83            context: e.context,
84        }
85    }
86}
87
88impl From<Error> for ErrorResponse {
89    fn from(e: Error) -> Self {
90        ErrorResponse {
91            code: e.code,
92            message: e.message,
93            context: e.context,
94        }
95    }
96}
97
98impl std::error::Error for Error {}
99
100impl std::fmt::Display for Error {
101    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
102        write!(f, "{} (code: {})", self.message, self.code)
103    }
104}