Skip to main content

dbsp/
error.rs

1use crate::{
2    RuntimeError, SchedulerError, operator::dynamic::balance::BalancerError,
3    storage::backend::StorageError,
4};
5use anyhow::Error as AnyError;
6use serde::{Serialize, Serializer, ser::SerializeStruct};
7use std::{
8    borrow::Cow,
9    error::Error as StdError,
10    fmt::{Display, Error as FmtError, Formatter},
11    io::Error as IOError,
12};
13use tracing::Level;
14
15pub trait DetailedError: StdError + Serialize {
16    fn error_code(&self) -> Cow<'static, str>;
17    fn log_level(&self) -> Level {
18        Level::ERROR
19    }
20}
21
22#[derive(Debug)]
23pub enum Error {
24    Scheduler(SchedulerError),
25    Runtime(RuntimeError),
26    IO(IOError),
27    Constructor(AnyError),
28    Storage(StorageError),
29    Balancer(BalancerError),
30}
31
32impl DetailedError for Error {
33    fn error_code(&self) -> Cow<'static, str> {
34        match self {
35            Self::Scheduler(error) => Cow::from(format!("SchedulerError.{}", error.error_code())),
36            Self::Runtime(error) => Cow::from(format!("RuntimeError.{}", error.error_code())),
37            Self::IO(_) => Cow::from("IOError"),
38            Self::Constructor(_) => Cow::from("CircuitConstructorError"),
39            Self::Storage(_) => Cow::from("StorageError"),
40            Self::Balancer(_) => Cow::from("BalancerError"),
41        }
42    }
43}
44
45impl Serialize for Error {
46    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
47    where
48        S: Serializer,
49    {
50        match self {
51            Self::Scheduler(error) => error.serialize(serializer),
52            Self::Runtime(error) => error.serialize(serializer),
53            Self::IO(error) => {
54                let mut ser = serializer.serialize_struct("IOError", 2)?;
55                ser.serialize_field("kind", &error.kind().to_string())?;
56                ser.serialize_field("os_error", &error.raw_os_error())?;
57                ser.end()
58            }
59            Self::Constructor(_) => serializer
60                .serialize_struct("CircuitConstructorError", 0)?
61                .end(),
62            Self::Storage(error) => error.serialize(serializer),
63            Self::Balancer(error) => error.serialize(serializer),
64        }
65    }
66}
67
68impl StdError for Error {}
69
70impl Display for Error {
71    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
72        match self {
73            Self::Scheduler(error) => {
74                write!(f, "scheduler error: {error}")
75            }
76            Self::Runtime(error) => {
77                write!(f, "runtime error: {error}")
78            }
79            Self::IO(error) => {
80                write!(f, "IO error: {error}")
81            }
82            Self::Constructor(error) => {
83                write!(f, "circuit construction error: {error}")
84            }
85            Self::Storage(error) => {
86                write!(f, "storage error: {error}")
87            }
88            Self::Balancer(error) => {
89                write!(f, "balancer error: {error}")
90            }
91        }
92    }
93}
94
95impl From<IOError> for Error {
96    fn from(error: IOError) -> Self {
97        Self::IO(error)
98    }
99}
100
101impl From<SchedulerError> for Error {
102    fn from(error: SchedulerError) -> Self {
103        Self::Scheduler(error)
104    }
105}
106
107impl From<RuntimeError> for Error {
108    fn from(error: RuntimeError) -> Self {
109        Self::Runtime(error)
110    }
111}
112
113impl From<StorageError> for Error {
114    fn from(error: StorageError) -> Self {
115        Self::Storage(error)
116    }
117}
118
119impl From<BalancerError> for Error {
120    fn from(error: BalancerError) -> Self {
121        Self::Balancer(error)
122    }
123}