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}