tokio/time/
error.rs

1//! Time error types.
2
3use std::error;
4use std::fmt;
5
6/// Errors encountered by the timer implementation.
7///
8/// Currently, there are two different errors that can occur:
9///
10/// * `shutdown` occurs when a timer operation is attempted, but the timer
11///   instance has been dropped. In this case, the operation will never be able
12///   to complete and the `shutdown` error is returned. This is a permanent
13///   error, i.e., once this error is observed, timer operations will never
14///   succeed in the future.
15///
16/// * `at_capacity` occurs when a timer operation is attempted, but the timer
17///   instance is currently handling its maximum number of outstanding sleep instances.
18///   In this case, the operation is not able to be performed at the current
19///   moment, and `at_capacity` is returned. This is a transient error, i.e., at
20///   some point in the future, if the operation is attempted again, it might
21///   succeed. Callers that observe this error should attempt to [shed load]. One
22///   way to do this would be dropping the future that issued the timer operation.
23///
24/// [shed load]: https://en.wikipedia.org/wiki/Load_Shedding
25#[derive(Debug, Copy, Clone)]
26pub struct Error(Kind);
27
28#[derive(Debug, Clone, Copy, Eq, PartialEq)]
29#[repr(u8)]
30pub(crate) enum Kind {
31    Shutdown = 1,
32    AtCapacity = 2,
33    Invalid = 3,
34}
35
36impl From<Kind> for Error {
37    fn from(k: Kind) -> Self {
38        Error(k)
39    }
40}
41
42/// Errors returned by `Timeout`.
43///
44/// This error is returned when a timeout expires before the function was able
45/// to finish.
46#[derive(Debug, PartialEq, Eq)]
47pub struct Elapsed(());
48
49#[derive(Debug)]
50pub(crate) enum InsertError {
51    Elapsed,
52}
53
54// ===== impl Error =====
55
56impl Error {
57    /// Creates an error representing a shutdown timer.
58    pub fn shutdown() -> Error {
59        Error(Kind::Shutdown)
60    }
61
62    /// Returns `true` if the error was caused by the timer being shutdown.
63    pub fn is_shutdown(&self) -> bool {
64        matches!(self.0, Kind::Shutdown)
65    }
66
67    /// Creates an error representing a timer at capacity.
68    pub fn at_capacity() -> Error {
69        Error(Kind::AtCapacity)
70    }
71
72    /// Returns `true` if the error was caused by the timer being at capacity.
73    pub fn is_at_capacity(&self) -> bool {
74        matches!(self.0, Kind::AtCapacity)
75    }
76
77    /// Creates an error representing a misconfigured timer.
78    pub fn invalid() -> Error {
79        Error(Kind::Invalid)
80    }
81
82    /// Returns `true` if the error was caused by the timer being misconfigured.
83    pub fn is_invalid(&self) -> bool {
84        matches!(self.0, Kind::Invalid)
85    }
86}
87
88impl error::Error for Error {}
89
90impl fmt::Display for Error {
91    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
92        let descr = match self.0 {
93            Kind::Shutdown => {
94                "the timer is shutdown, must be called from the context of Tokio runtime"
95            }
96            Kind::AtCapacity => "timer is at capacity and cannot create a new entry",
97            Kind::Invalid => "timer duration exceeds maximum duration",
98        };
99        write!(fmt, "{}", descr)
100    }
101}
102
103// ===== impl Elapsed =====
104
105impl Elapsed {
106    pub(crate) fn new() -> Self {
107        Elapsed(())
108    }
109}
110
111impl fmt::Display for Elapsed {
112    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
113        "deadline has elapsed".fmt(fmt)
114    }
115}
116
117impl std::error::Error for Elapsed {}
118
119impl From<Elapsed> for std::io::Error {
120    fn from(_err: Elapsed) -> std::io::Error {
121        std::io::ErrorKind::TimedOut.into()
122    }
123}