bgpkit_parser/parser/bmp/
error.rs

1use crate::bmp::messages::headers::BmpPeerType;
2use crate::bmp::messages::initiation_message::InitiationTlvType;
3use crate::bmp::messages::peer_down_notification::PeerDownReason;
4use crate::bmp::messages::peer_up_notification::PeerUpTlvType;
5use crate::bmp::messages::route_mirroring::RouteMirroringInfo;
6use crate::bmp::messages::termination_message::{TerminationReason, TerminationTlvType};
7use crate::bmp::messages::BmpMsgType;
8use crate::ParserError;
9use num_enum::TryFromPrimitiveError;
10use std::error::Error;
11use std::fmt::{Display, Formatter};
12
13#[derive(Debug, PartialEq, Clone, Eq)]
14pub enum ParserBmpError {
15    InvalidOpenBmpHeader,
16    UnsupportedOpenBmpMessage,
17    UnknownTlvType,
18    UnknownTlvValue,
19    CorruptedBmpMessage,
20    CorruptedBgpMessage(String),
21    TruncatedBmpMessage,
22}
23
24impl Display for ParserBmpError {
25    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
26        match self {
27            ParserBmpError::InvalidOpenBmpHeader => {
28                write!(f, "Invalid OpenBMP header")
29            }
30            ParserBmpError::UnsupportedOpenBmpMessage => {
31                write!(f, "Unsupported OpenBMP message")
32            }
33            ParserBmpError::CorruptedBmpMessage => {
34                write!(f, "Corrupted BMP message")
35            }
36            ParserBmpError::TruncatedBmpMessage => {
37                write!(f, "Truncated BMP message")
38            }
39            ParserBmpError::UnknownTlvType => {
40                write!(f, "Unknown TLV type")
41            }
42            ParserBmpError::UnknownTlvValue => {
43                write!(f, "Unknown TLV value")
44            }
45            ParserBmpError::CorruptedBgpMessage(s) => {
46                write!(f, "Corrupted BGP message: {}", s)
47            }
48        }
49    }
50}
51
52impl Error for ParserBmpError {}
53
54// TODO: These conversions make the error difficult to debug as they drop all of the error context
55impl From<std::io::Error> for ParserBmpError {
56    fn from(_: std::io::Error) -> Self {
57        ParserBmpError::InvalidOpenBmpHeader
58    }
59}
60
61impl From<ParserError> for ParserBmpError {
62    fn from(e: ParserError) -> Self {
63        ParserBmpError::CorruptedBgpMessage(e.to_string())
64    }
65}
66
67impl From<TryFromPrimitiveError<BmpMsgType>> for ParserBmpError {
68    fn from(_: TryFromPrimitiveError<BmpMsgType>) -> Self {
69        ParserBmpError::InvalidOpenBmpHeader
70    }
71}
72
73impl From<TryFromPrimitiveError<BmpPeerType>> for ParserBmpError {
74    fn from(_: TryFromPrimitiveError<BmpPeerType>) -> Self {
75        ParserBmpError::CorruptedBmpMessage
76    }
77}
78
79impl From<TryFromPrimitiveError<InitiationTlvType>> for ParserBmpError {
80    fn from(_: TryFromPrimitiveError<InitiationTlvType>) -> Self {
81        ParserBmpError::UnknownTlvType
82    }
83}
84
85impl From<TryFromPrimitiveError<PeerUpTlvType>> for ParserBmpError {
86    fn from(_: TryFromPrimitiveError<PeerUpTlvType>) -> Self {
87        ParserBmpError::UnknownTlvType
88    }
89}
90
91impl From<TryFromPrimitiveError<RouteMirroringInfo>> for ParserBmpError {
92    fn from(_: TryFromPrimitiveError<RouteMirroringInfo>) -> Self {
93        ParserBmpError::CorruptedBmpMessage
94    }
95}
96
97impl From<TryFromPrimitiveError<TerminationTlvType>> for ParserBmpError {
98    fn from(_: TryFromPrimitiveError<TerminationTlvType>) -> Self {
99        ParserBmpError::UnknownTlvType
100    }
101}
102
103impl From<TryFromPrimitiveError<TerminationReason>> for ParserBmpError {
104    fn from(_: TryFromPrimitiveError<TerminationReason>) -> Self {
105        ParserBmpError::UnknownTlvValue
106    }
107}
108
109impl From<TryFromPrimitiveError<PeerDownReason>> for ParserBmpError {
110    fn from(_: TryFromPrimitiveError<PeerDownReason>) -> Self {
111        ParserBmpError::UnknownTlvValue
112    }
113}
114
115#[cfg(test)]
116mod tests {
117    use super::*;
118
119    #[test]
120    fn test_parser_error_display() {
121        assert_eq!(
122            ParserBmpError::InvalidOpenBmpHeader.to_string(),
123            "Invalid OpenBMP header"
124        );
125        assert_eq!(
126            ParserBmpError::UnsupportedOpenBmpMessage.to_string(),
127            "Unsupported OpenBMP message"
128        );
129        assert_eq!(
130            ParserBmpError::CorruptedBmpMessage.to_string(),
131            "Corrupted BMP message"
132        );
133        assert_eq!(
134            ParserBmpError::CorruptedBgpMessage("test".to_string()).to_string(),
135            "Corrupted BGP message: test"
136        );
137        assert_eq!(
138            ParserBmpError::TruncatedBmpMessage.to_string(),
139            "Truncated BMP message"
140        );
141        assert_eq!(
142            ParserBmpError::UnknownTlvType.to_string(),
143            "Unknown TLV type"
144        );
145        assert_eq!(
146            ParserBmpError::UnknownTlvValue.to_string(),
147            "Unknown TLV value"
148        );
149    }
150
151    #[test]
152    fn test_error_conversions() {
153        assert_eq!(
154            ParserBmpError::from(std::io::Error::other("test")),
155            ParserBmpError::InvalidOpenBmpHeader
156        );
157        assert_eq!(
158            ParserBmpError::from(ParserError::ParseError("test".to_string())),
159            ParserBmpError::CorruptedBgpMessage("Error: test".to_string())
160        );
161        assert_eq!(
162            ParserBmpError::from(TryFromPrimitiveError::<BmpMsgType>::new(0)),
163            ParserBmpError::InvalidOpenBmpHeader
164        );
165        assert_eq!(
166            ParserBmpError::from(TryFromPrimitiveError::<BmpPeerType>::new(0)),
167            ParserBmpError::CorruptedBmpMessage
168        );
169        assert_eq!(
170            ParserBmpError::from(TryFromPrimitiveError::<InitiationTlvType>::new(0)),
171            ParserBmpError::UnknownTlvType
172        );
173        assert_eq!(
174            ParserBmpError::from(TryFromPrimitiveError::<RouteMirroringInfo>::new(0)),
175            ParserBmpError::CorruptedBmpMessage
176        );
177        assert_eq!(
178            ParserBmpError::from(TryFromPrimitiveError::<TerminationTlvType>::new(0)),
179            ParserBmpError::UnknownTlvType
180        );
181        assert_eq!(
182            ParserBmpError::from(TryFromPrimitiveError::<PeerUpTlvType>::new(0)),
183            ParserBmpError::UnknownTlvType
184        );
185        assert_eq!(
186            ParserBmpError::from(TryFromPrimitiveError::<TerminationReason>::new(0)),
187            ParserBmpError::UnknownTlvValue
188        );
189        assert_eq!(
190            ParserBmpError::from(TryFromPrimitiveError::<PeerDownReason>::new(0)),
191            ParserBmpError::UnknownTlvValue
192        );
193    }
194}