1//! Error handling for [`P2PStream`](crate::P2PStream).
23use std::io;
45use reth_eth_wire_types::{DisconnectReason, UnknownDisconnectReason};
6use reth_primitives_traits::GotExpected;
78use crate::{capability::SharedCapabilityError, ProtocolVersion};
910/// Errors when sending/receiving p2p messages. These should result in kicking the peer.
11#[derive(thiserror::Error, Debug)]
12pub enum P2PStreamError {
13/// I/O error.
14#[error(transparent)]
15Io(#[from] io::Error),
1617/// RLP encoding/decoding error.
18#[error(transparent)]
19Rlp(#[from] alloy_rlp::Error),
2021/// Error in compression/decompression using Snappy.
22#[error(transparent)]
23Snap(#[from] snap::Error),
2425/// Error during the P2P handshake.
26#[error(transparent)]
27HandshakeError(#[from] P2PHandshakeError),
2829/// Message size exceeds maximum length error.
30#[error("message size ({message_size}) exceeds max length ({max_size})")]
31MessageTooBig {
32/// The actual size of the message received.
33message_size: usize,
34/// The maximum allowed size for the message.
35max_size: usize,
36 },
3738/// Unknown reserved P2P message ID error.
39#[error("unknown reserved p2p message id: {0}")]
40UnknownReservedMessageId(u8),
4142/// Empty protocol message received error.
43#[error("empty protocol message received")]
44EmptyProtocolMessage,
4546/// Error related to the Pinger.
47#[error(transparent)]
48PingerError(#[from] PingerError),
4950/// Ping timeout error.
51#[error("ping timed out with")]
52PingTimeout,
5354/// Error parsing shared capabilities.
55#[error(transparent)]
56ParseSharedCapability(#[from] SharedCapabilityError),
5758/// Capability not supported on the stream to this peer.
59#[error("capability not supported on stream to this peer")]
60CapabilityNotShared,
6162/// Mismatched protocol version error.
63#[error("mismatched protocol version in Hello message: {0}")]
64MismatchedProtocolVersion(GotExpected<ProtocolVersion>),
6566/// Too many messages buffered before sending.
67#[error("too many messages buffered before sending")]
68SendBufferFull,
6970/// Disconnected error.
71#[error("disconnected")]
72Disconnected(DisconnectReason),
7374/// Unknown disconnect reason error.
75#[error("unknown disconnect reason: {0}")]
76UnknownDisconnectReason(#[from] UnknownDisconnectReason),
77}
7879// === impl P2PStreamError ===
8081impl P2PStreamError {
82/// Returns the [`DisconnectReason`] if it is the `Disconnected` variant.
83pub const fn as_disconnected(&self) -> Option<DisconnectReason> {
84let reason = match self{
85Self::HandshakeError(P2PHandshakeError::Disconnected(reason)) |
86Self::Disconnected(reason) => reason,
87_ => return None,
88 };
8990Some(*reason)
91 }
92}
9394/// Errors when conducting a p2p handshake.
95#[derive(thiserror::Error, Debug, Clone, Eq, PartialEq)]
96pub enum P2PHandshakeError {
97/// Hello message received/sent outside of handshake error.
98#[error("hello message can only be recv/sent in handshake")]
99HelloNotInHandshake,
100101/// Received a non-hello message when trying to handshake.
102#[error("received non-hello message when trying to handshake")]
103NonHelloMessageInHandshake,
104105/// No capabilities shared with the peer.
106#[error("no capabilities shared with peer")]
107NoSharedCapabilities,
108109/// No response received when sending out handshake.
110#[error("no response received when sending out handshake")]
111NoResponse,
112113/// Handshake timed out.
114#[error("handshake timed out")]
115Timeout,
116117/// Disconnected by peer with a specific reason.
118#[error("disconnected by peer: {0}")]
119Disconnected(DisconnectReason),
120121/// Error decoding a message during handshake.
122#[error("error decoding a message during handshake: {0}")]
123DecodeError(#[from] alloy_rlp::Error),
124}
125126/// An error that can occur when interacting with a pinger.
127#[derive(Debug, thiserror::Error)]
128pub enum PingerError {
129/// An unexpected pong was received while the pinger was in the `Ready` state.
130#[error("pong received while ready")]
131UnexpectedPong,
132}