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}