libp2p_swarm/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 std::{fmt, io};
22
23use crate::{transport::TransportError, Multiaddr, PeerId};
24
25/// Errors that can occur in the context of an established `Connection`.
26#[derive(Debug)]
27pub enum ConnectionError {
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 keep-alive timeout expired.
33 KeepAliveTimeout,
34}
35
36impl fmt::Display for ConnectionError {
37 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38 match self {
39 ConnectionError::IO(err) => write!(f, "Connection error: I/O error: {err}"),
40 ConnectionError::KeepAliveTimeout => {
41 write!(f, "Connection closed due to expired keep-alive timeout.")
42 }
43 }
44 }
45}
46
47impl std::error::Error for ConnectionError {
48 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
49 match self {
50 ConnectionError::IO(err) => Some(err),
51 ConnectionError::KeepAliveTimeout => None,
52 }
53 }
54}
55
56impl From<io::Error> for ConnectionError {
57 fn from(error: io::Error) -> Self {
58 ConnectionError::IO(error)
59 }
60}
61
62/// Errors that can occur in the context of a pending outgoing `Connection`.
63///
64/// Note: Addresses for an outbound connection are dialed in parallel. Thus, compared to
65/// [`PendingInboundConnectionError`], one or more [`TransportError`]s can occur for a single
66/// connection.
67#[derive(Debug)]
68pub(crate) enum PendingOutboundConnectionError {
69 /// An error occurred while negotiating the transport protocol(s) on a connection.
70 Transport(Vec<(Multiaddr, TransportError<io::Error>)>),
71
72 /// Pending connection attempt has been aborted.
73 Aborted,
74
75 /// The peer identity obtained on the connection did not
76 /// match the one that was expected.
77 WrongPeerId {
78 obtained: PeerId,
79 address: Multiaddr,
80 },
81
82 /// The connection was dropped because it resolved to our own [`PeerId`].
83 LocalPeerId { address: Multiaddr },
84}
85
86/// Errors that can occur in the context of a pending incoming `Connection`.
87#[derive(Debug)]
88pub(crate) enum PendingInboundConnectionError {
89 /// An error occurred while negotiating the transport protocol(s) on a connection.
90 Transport(TransportError<io::Error>),
91
92 /// Pending connection attempt has been aborted.
93 Aborted,
94
95 /// The connection was dropped because it resolved to our own [`PeerId`].
96 LocalPeerId { address: Multiaddr },
97}