Coverage Report

Created: 2026-01-10 06:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/h2/src/proto/error.rs
Line
Count
Source
1
use crate::codec::SendError;
2
use crate::frame::{Reason, StreamId};
3
4
use bytes::Bytes;
5
use std::fmt;
6
use std::io;
7
8
/// Either an H2 reason  or an I/O error
9
#[derive(Clone, Debug)]
10
pub enum Error {
11
    Reset(StreamId, Reason, Initiator),
12
    GoAway(Bytes, Reason, Initiator),
13
    Io(io::ErrorKind, Option<String>),
14
}
15
16
pub struct GoAway {
17
    pub debug_data: Bytes,
18
    pub reason: Reason,
19
}
20
21
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
22
pub enum Initiator {
23
    User,
24
    Library,
25
    Remote,
26
}
27
28
impl Error {
29
99.5k
    pub(crate) fn is_local(&self) -> bool {
30
99.5k
        match *self {
31
99.5k
            Self::Reset(_, _, initiator) | Self::GoAway(_, _, initiator) => initiator.is_local(),
32
0
            Self::Io(..) => true,
33
        }
34
99.5k
    }
35
36
0
    pub(crate) fn user_go_away(reason: Reason) -> Self {
37
0
        Self::GoAway(Bytes::new(), reason, Initiator::User)
38
0
    }
39
40
79.5k
    pub(crate) fn library_reset(stream_id: StreamId, reason: Reason) -> Self {
41
79.5k
        Self::Reset(stream_id, reason, Initiator::Library)
42
79.5k
    }
43
44
12.4k
    pub(crate) fn library_go_away(reason: Reason) -> Self {
45
12.4k
        Self::GoAway(Bytes::new(), reason, Initiator::Library)
46
12.4k
    }
47
48
0
    pub(crate) fn library_go_away_data(reason: Reason, debug_data: impl Into<Bytes>) -> Self {
49
0
        Self::GoAway(debug_data.into(), reason, Initiator::Library)
50
0
    }
51
52
590
    pub(crate) fn remote_reset(stream_id: StreamId, reason: Reason) -> Self {
53
590
        Self::Reset(stream_id, reason, Initiator::Remote)
54
590
    }
55
56
5.33k
    pub(crate) fn remote_go_away(debug_data: Bytes, reason: Reason) -> Self {
57
5.33k
        Self::GoAway(debug_data, reason, Initiator::Remote)
58
5.33k
    }
59
}
60
61
impl Initiator {
62
99.5k
    fn is_local(&self) -> bool {
63
99.5k
        match *self {
64
98.3k
            Self::User | Self::Library => true,
65
1.20k
            Self::Remote => false,
66
        }
67
99.5k
    }
68
69
78.5k
    pub(crate) fn is_library(&self) -> bool {
70
78.5k
        matches!(self, Self::Library)
71
78.5k
    }
72
}
73
74
impl fmt::Display for Error {
75
0
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
76
0
        match *self {
77
0
            Self::Reset(_, reason, _) | Self::GoAway(_, reason, _) => reason.fmt(fmt),
78
0
            Self::Io(_, Some(ref inner)) => inner.fmt(fmt),
79
0
            Self::Io(kind, None) => io::Error::from(kind).fmt(fmt),
80
        }
81
0
    }
82
}
83
84
impl From<io::ErrorKind> for Error {
85
0
    fn from(src: io::ErrorKind) -> Self {
86
0
        Error::Io(src, None)
87
0
    }
88
}
89
90
impl From<io::Error> for Error {
91
190k
    fn from(src: io::Error) -> Self {
92
190k
        Error::Io(src.kind(), src.get_ref().map(|inner| inner.to_string()))
93
190k
    }
94
}
95
96
impl From<Error> for SendError {
97
0
    fn from(src: Error) -> Self {
98
0
        Self::Connection(src)
99
0
    }
100
}