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}