1use std::{string::FromUtf8Error, str::Utf8Error};
2
3use rain_metaboard_subgraph::metaboard_client::MetaboardSubgraphClientError;
4
5use crate::meta::KnownMagic;
6
7#[derive(Debug)]
9pub enum Error {
10 CorruptMeta,
11 InvalidHash,
12 UnknownMeta,
13 UnknownMagic,
14 NoRecordFound,
15 UnsupportedMeta,
16 BiggerThan32Bytes,
17 InflateError(String),
18 InvalidInput(String),
19 InvalidUrl(String),
20 Utf8Error(Utf8Error),
21 FromUtf8Error(FromUtf8Error),
22 ReqwestError(reqwest::Error),
23 SerdeCborError(serde_cbor::Error),
24 SerdeJsonError(serde_json::Error),
25 AbiCoderError(alloy::sol_types::Error),
26 ValidationErrors(validator::ValidationErrors),
27 DecodeHexStringError(alloy::primitives::hex::FromHexError),
28 InvalidMetaMagic(KnownMagic, KnownMagic),
29 MetaboardSubgraphClientError(MetaboardSubgraphClientError),
30}
31
32impl std::fmt::Display for Error {
33 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 match self {
35 Error::CorruptMeta => f.write_str("corrupt meta"),
36 Error::UnknownMeta => f.write_str("unknown meta"),
37 Error::UnknownMagic => f.write_str("unknown magic"),
38 Error::UnsupportedMeta => f.write_str("unsupported meta"),
39 Error::InvalidHash => f.write_str("invalid keccak256 hash"),
40 Error::NoRecordFound => f.write_str("found no matching record"),
41 Error::BiggerThan32Bytes => {
42 f.write_str("unexpected input size, must be 32 bytes or less")
43 }
44 Error::InvalidInput(v) => write!(f, "invalid input: {}", v),
45 Error::InvalidUrl(v) => write!(f, "invalid URL: {}", v),
46 Error::ReqwestError(v) => write!(f, "{}", v),
47 Error::InflateError(v) => write!(f, "{}", v),
48 Error::Utf8Error(v) => write!(f, "{}", v),
49 Error::AbiCoderError(v) => write!(f, "{}", v),
50 Error::SerdeCborError(v) => write!(f, "{}", v),
51 Error::SerdeJsonError(v) => write!(f, "{}", v),
52 Error::FromUtf8Error(v) => write!(f, "{}", v),
53 Error::DecodeHexStringError(v) => write!(f, "{}", v),
54 Error::ValidationErrors(v) => write!(f, "{}", v),
55 Error::InvalidMetaMagic(expected, actual) => {
56 write!(
57 f,
58 "invalid meta magic: expected {:?}, got {:?}",
59 expected, actual
60 )
61 }
62 Error::MetaboardSubgraphClientError(v) => write!(f, "{}", v),
63 }
64 }
65}
66
67impl std::error::Error for Error {}
68
69impl From<serde_json::Error> for Error {
70 fn from(value: serde_json::Error) -> Self {
71 Error::SerdeJsonError(value)
72 }
73}
74
75impl From<serde_cbor::Error> for Error {
76 fn from(value: serde_cbor::Error) -> Self {
77 Error::SerdeCborError(value)
78 }
79}
80
81impl From<FromUtf8Error> for Error {
82 fn from(value: FromUtf8Error) -> Self {
83 Error::FromUtf8Error(value)
84 }
85}
86
87impl From<Utf8Error> for Error {
88 fn from(value: Utf8Error) -> Self {
89 Error::Utf8Error(value)
90 }
91}
92
93impl From<validator::ValidationErrors> for Error {
94 fn from(value: validator::ValidationErrors) -> Self {
95 Error::ValidationErrors(value)
96 }
97}
98
99impl From<alloy::sol_types::Error> for Error {
100 fn from(value: alloy::sol_types::Error) -> Self {
101 Error::AbiCoderError(value)
102 }
103}
104
105#[cfg(test)]
106mod tests {
107 use super::*;
108
109 #[test]
112 fn test_display_fixed_strings() {
113 assert_eq!(Error::CorruptMeta.to_string(), "corrupt meta");
114 assert_eq!(Error::UnknownMeta.to_string(), "unknown meta");
115 assert_eq!(Error::UnknownMagic.to_string(), "unknown magic");
116 assert_eq!(Error::UnsupportedMeta.to_string(), "unsupported meta");
117 assert_eq!(Error::InvalidHash.to_string(), "invalid keccak256 hash");
118 assert_eq!(Error::NoRecordFound.to_string(), "found no matching record");
119 assert_eq!(
120 Error::BiggerThan32Bytes.to_string(),
121 "unexpected input size, must be 32 bytes or less"
122 );
123 }
124
125 #[test]
127 fn test_display_formatted_wrappers() {
128 assert_eq!(
129 Error::InvalidInput("abc".to_string()).to_string(),
130 "invalid input: abc"
131 );
132 assert_eq!(
133 Error::InvalidUrl("not-a-url".to_string()).to_string(),
134 "invalid URL: not-a-url"
135 );
136 assert_eq!(Error::InflateError("boom".to_string()).to_string(), "boom");
137 }
138
139 #[test]
141 fn test_display_invalid_meta_magic_field_order() {
142 let err = Error::InvalidMetaMagic(KnownMagic::RainMetaDocumentV1, KnownMagic::OpMetaV1);
143 assert_eq!(
144 err.to_string(),
145 "invalid meta magic: expected RainMetaDocumentV1, got OpMetaV1"
146 );
147 }
148
149 #[test]
152 fn test_from_serde_json_routes_to_serde_json_error() {
153 let src = serde_json::from_str::<serde_json::Value>("{oops").unwrap_err();
154 let msg = src.to_string();
155 let err: Error = src.into();
156 match err {
157 Error::SerdeJsonError(e) => assert_eq!(e.to_string(), msg),
158 other => panic!("wrong variant: {:?}", other),
159 }
160 }
161
162 #[test]
163 fn test_from_utf8_error_routes_to_utf8_error() {
164 #[allow(invalid_from_utf8)]
166 let src = std::str::from_utf8(&[0xff]).unwrap_err();
167 let err: Error = src.into();
168 match err {
169 Error::Utf8Error(e) => assert_eq!(e, src),
170 other => panic!("wrong variant: {:?}", other),
171 }
172 }
173
174 #[test]
175 fn test_from_from_utf8_error_routes_to_from_utf8_error() {
176 let src = String::from_utf8(vec![0xff]).unwrap_err();
177 let msg = src.to_string();
178 let err: Error = src.into();
179 match err {
180 Error::FromUtf8Error(e) => assert_eq!(e.to_string(), msg),
181 other => panic!("wrong variant: {:?}", other),
182 }
183 }
184}