-
Notifications
You must be signed in to change notification settings - Fork 52
Expand file tree
/
Copy patherror.rs
More file actions
205 lines (168 loc) · 6.48 KB
/
error.rs
File metadata and controls
205 lines (168 loc) · 6.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
//! Core tracker errors.
//!
//! This module defines the error types used internally by the `BitTorrent`
//! tracker core.
//!
//! These errors encapsulate issues such as whitelisting violations, invalid
//! peer key data, and database persistence failures. Each error variant
//! includes contextual information (such as source code location) to facilitate
//! debugging.
use std::panic::Location;
use bittorrent_primitives::info_hash::InfoHash;
use torrust_tracker_located_error::LocatedError;
use super::authentication::key::ParseKeyError;
use super::databases;
use crate::authentication;
/// Wrapper for all errors returned by the tracker core.
#[derive(thiserror::Error, Debug, Clone)]
pub enum TrackerCoreError {
/// Error returned when there was an error with the tracker core announce handler.
#[error("Tracker core announce error: {source}")]
AnnounceError { source: AnnounceError },
/// Error returned when there was an error with the tracker core scrape handler.
#[error("Tracker core scrape error: {source}")]
ScrapeError { source: ScrapeError },
/// Error returned when there was an error with the tracker core whitelist.
#[error("Tracker core whitelist error: {source}")]
WhitelistError { source: WhitelistError },
/// Error returned when there was an error with the authentication in the tracker core.
#[error("Tracker core authentication error: {source}")]
AuthenticationError { source: authentication::key::Error },
}
impl From<AnnounceError> for TrackerCoreError {
fn from(announce_error: AnnounceError) -> Self {
Self::AnnounceError { source: announce_error }
}
}
impl From<ScrapeError> for TrackerCoreError {
fn from(scrape_error: ScrapeError) -> Self {
Self::ScrapeError { source: scrape_error }
}
}
impl From<WhitelistError> for TrackerCoreError {
fn from(whitelist_error: WhitelistError) -> Self {
Self::WhitelistError { source: whitelist_error }
}
}
impl From<authentication::key::Error> for TrackerCoreError {
fn from(whitelist_error: authentication::key::Error) -> Self {
Self::AuthenticationError { source: whitelist_error }
}
}
/// Errors related to announce requests.
#[derive(thiserror::Error, Debug, Clone)]
pub enum AnnounceError {
/// Wraps errors related to torrent whitelisting.
#[error("Whitelist error: {0}")]
Whitelist(#[from] WhitelistError),
/// Wraps errors related to database.
#[error("Database error: {0}")]
Database(#[from] databases::error::Error),
}
/// Errors related to scrape requests.
#[derive(thiserror::Error, Debug, Clone)]
pub enum ScrapeError {
/// Wraps errors related to torrent whitelisting.
#[error("Whitelist error: {0}")]
Whitelist(#[from] WhitelistError),
}
/// Errors related to torrent whitelisting.
///
/// This error is returned when an operation involves a torrent that is not
/// present in the whitelist.
#[derive(thiserror::Error, Debug, Clone, PartialEq, Eq)]
pub enum WhitelistError {
/// Indicates that the torrent identified by `info_hash` is not whitelisted.
#[error("The torrent: {info_hash}, is not whitelisted, {location}")]
TorrentNotWhitelisted {
info_hash: InfoHash,
location: &'static Location<'static>,
},
}
/// Errors related to peer key operations.
///
/// This error type covers issues encountered during the handling of peer keys,
/// including validation of key durations, parsing errors, and database
/// persistence problems.
#[allow(clippy::module_name_repetitions)]
#[derive(thiserror::Error, Debug, Clone)]
pub enum PeerKeyError {
/// Returned when the duration specified for the peer key exceeds the
/// maximum.
#[error("Invalid peer key duration: {seconds_valid:?}, is not valid")]
DurationOverflow { seconds_valid: u64 },
/// Returned when the provided peer key is invalid.
#[error("Invalid key: {key}")]
InvalidKey {
key: String,
source: LocatedError<'static, ParseKeyError>,
},
/// Returned when persisting the peer key to the database fails.
#[error("Can't persist key: {source}")]
DatabaseError {
source: LocatedError<'static, databases::error::Error>,
},
}
#[cfg(test)]
mod tests {
mod whitelist_error {
use crate::error::WhitelistError;
use crate::test_helpers::tests::sample_info_hash;
#[test]
fn torrent_not_whitelisted() {
let err = WhitelistError::TorrentNotWhitelisted {
info_hash: sample_info_hash(),
location: std::panic::Location::caller(),
};
let err_msg = format!("{err}");
assert!(
err_msg.contains(&format!("The torrent: {}, is not whitelisted", sample_info_hash())),
"Error message did not contain expected text: {err_msg}"
);
}
}
mod peer_key_error {
use torrust_tracker_located_error::Located;
use crate::databases::driver::Driver;
use crate::error::PeerKeyError;
use crate::{authentication, databases};
#[test]
fn duration_overflow() {
let seconds_valid = 100;
let err = PeerKeyError::DurationOverflow { seconds_valid };
let err_msg = format!("{err}");
assert!(
err_msg.contains(&format!("Invalid peer key duration: {seconds_valid}")),
"Error message did not contain expected text: {err_msg}"
);
}
#[test]
fn parsing_from_string() {
let err = authentication::key::ParseKeyError::InvalidKeyLength;
let err = PeerKeyError::InvalidKey {
key: "INVALID KEY".to_string(),
source: Located(err).into(),
};
let err_msg = format!("{err}");
assert!(
err_msg.contains(&"Invalid key: INVALID KEY".to_string()),
"Error message did not contain expected text: {err_msg}"
);
}
#[test]
fn persisting_into_database() {
let err = databases::error::Error::InsertFailed {
location: std::panic::Location::caller(),
driver: Driver::Sqlite3,
};
let err = PeerKeyError::DatabaseError {
source: Located(err).into(),
};
let err_msg = format!("{err}");
assert!(
err_msg.contains(&"Can't persist key".to_string()),
"Error message did not contain expected text: {err}"
);
}
}
}