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
// src/adaptive_concurrency/http.rs
use crateError as CrateError; // Crate-level error type
use Snafu;
/// A generic error enumeration for HTTP-related issues.
/// Specific client integrations (like Hyper or Reqwest) can define their own
/// errors and provide `From` implementations to convert to this `HttpError`
/// or directly to `CrateError`.
///
/// The `Controller` might look for this specific error type if it needs to
/// make decisions based on "is this an HTTP protocol error vs. a network error".
// // Implement conversion to the main crate error type.
// // This allows services returning specific HttpErrors (like HyperHttpError or a ReqwestHttpError)
// // to be compatible with AdaptiveConcurrencyLimit which expects S::Error: Into<CrateError>.
// impl From<HttpError> for CrateError {
// fn from(e: HttpError) -> Self {
// Box::new(e)
// }
// }
// --- Example of how a specific integration might use this ---
// In, for example, a hypothetical hyper_integration.rs:
/*
mod hyper_integration {
use super::HttpError as GenericHttpError; // The one defined above
use crate::Error as CrateError;
use hyper;
use snafu::Snafu;
#[derive(Debug, Snafu)]
pub enum SpecificHyperError {
#[snafu(display("Hyper client error: {}", source))]
Client { source: hyper::Error },
// other hyper specific errors
}
impl From<SpecificHyperError> for GenericHttpError {
fn from(e: SpecificHyperError) -> Self {
match e {
SpecificHyperError::Client { source } => {
if source.is_timeout() {
GenericHttpError::Timeout
} else if source.is_connect() || source.is_incomplete_message() {
GenericHttpError::Transport { source: Box::new(source) }
} else {
GenericHttpError::ClientError { source: Box::new(source) }
}
}
}
}
}
// And then SpecificHyperError would also implement `From<SpecificHyperError> for CrateError`
// often via its `From<SpecificHyperError> for GenericHttpError` impl.
impl From<SpecificHyperError> for CrateError {
fn from(e: SpecificHyperError) -> Self {
Box::new(GenericHttpError::from(e))
}
}
}
*/
// No specific service implementations here, as those are in their respective
// integration files (e.g., reqwest_integration.rs).
// The primary `tower::Service` trait is the main abstraction for services.