libp2p_core/connection/
error.rs

1// Copyright 2018 Parity Technologies (UK) Ltd.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and associated documentation files (the "Software"),
5// to deal in the Software without restriction, including without limitation
6// the rights to use, copy, modify, merge, publish, distribute, sublicense,
7// and/or sell copies of the Software, and to permit persons to whom the
8// Software is furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19// DEALINGS IN THE SOFTWARE.
20
21use crate::connection::ConnectionLimit;
22use crate::transport::TransportError;
23use std::{io, fmt};
24
25/// Errors that can occur in the context of an established `Connection`.
26#[derive(Debug)]
27pub enum ConnectionError<THandlerErr> {
28    /// An I/O error occurred on the connection.
29    // TODO: Eventually this should also be a custom error?
30    IO(io::Error),
31
32    /// The connection handler produced an error.
33    Handler(THandlerErr),
34}
35
36impl<THandlerErr> fmt::Display
37for ConnectionError<THandlerErr>
38where
39    THandlerErr: fmt::Display,
40{
41    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42        match self {
43            ConnectionError::IO(err) =>
44                write!(f, "Connection error: I/O error: {}", err),
45            ConnectionError::Handler(err) =>
46                write!(f, "Connection error: Handler error: {}", err),
47        }
48    }
49}
50
51impl<THandlerErr> std::error::Error
52for ConnectionError<THandlerErr>
53where
54    THandlerErr: std::error::Error + 'static,
55{
56    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
57        match self {
58            ConnectionError::IO(err) => Some(err),
59            ConnectionError::Handler(err) => Some(err),
60        }
61    }
62}
63
64/// Errors that can occur in the context of a pending `Connection`.
65#[derive(Debug)]
66pub enum PendingConnectionError<TTransErr> {
67    /// An error occurred while negotiating the transport protocol(s).
68    Transport(TransportError<TTransErr>),
69
70    /// The peer identity obtained on the connection did not
71    /// match the one that was expected or is otherwise invalid.
72    InvalidPeerId,
73
74    /// The connection was dropped because the connection limit
75    /// for a peer has been reached.
76    ConnectionLimit(ConnectionLimit),
77
78    /// An I/O error occurred on the connection.
79    // TODO: Eventually this should also be a custom error?
80    IO(io::Error),
81}
82
83impl<TTransErr> fmt::Display
84for PendingConnectionError<TTransErr>
85where
86    TTransErr: fmt::Display,
87{
88    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89        match self {
90            PendingConnectionError::IO(err) =>
91                write!(f, "Pending connection: I/O error: {}", err),
92            PendingConnectionError::Transport(err) =>
93                write!(f, "Pending connection: Transport error: {}", err),
94            PendingConnectionError::InvalidPeerId =>
95                write!(f, "Pending connection: Invalid peer ID."),
96            PendingConnectionError::ConnectionLimit(l) =>
97                write!(f, "Connection error: Connection limit: {}.", l),
98        }
99    }
100}
101
102impl<TTransErr> std::error::Error
103for PendingConnectionError<TTransErr>
104where
105    TTransErr: std::error::Error + 'static
106{
107    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
108        match self {
109            PendingConnectionError::IO(err) => Some(err),
110            PendingConnectionError::Transport(err) => Some(err),
111            PendingConnectionError::InvalidPeerId => None,
112            PendingConnectionError::ConnectionLimit(..) => None,
113        }
114    }
115}