Skip to content

Commit

Permalink
feat(transport): HttpError (alloy-rs#882)
Browse files Browse the repository at this point in the history
  • Loading branch information
yash-atreya authored Jun 12, 2024
1 parent ed8a6ba commit cfb8df7
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 8 deletions.
8 changes: 4 additions & 4 deletions crates/transport-http/src/hyper_transport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,10 @@ where
trace!(body = %String::from_utf8_lossy(&body), "response body");

if status != hyper::StatusCode::OK {
return Err(TransportErrorKind::custom_str(&format!(
"HTTP error {status} with body: {}",
String::from_utf8_lossy(&body)
)));
return Err(TransportErrorKind::http_error(
status.as_u16(),
String::from_utf8_lossy(&body).into_owned(),
));
}

// Deserialize a Box<RawValue> from the body. If deserialization fails, return
Expand Down
8 changes: 4 additions & 4 deletions crates/transport-http/src/reqwest_transport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ impl Http<Client> {
trace!(body = %String::from_utf8_lossy(&body), "response body");

if status != reqwest::StatusCode::OK {
return Err(TransportErrorKind::custom_str(&format!(
"HTTP error {status} with body: {}",
String::from_utf8_lossy(&body)
)));
return Err(TransportErrorKind::http_error(
status.as_u16(),
String::from_utf8_lossy(&body).into_owned(),
));
}

// Deserialize a Box<RawValue> from the body. If deserialization fails, return
Expand Down
42 changes: 42 additions & 0 deletions crates/transport/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ pub enum TransportErrorKind {
#[error("subscriptions are not available on this provider")]
PubsubUnavailable,

/// HTTP Error with code and body
#[error("{0}")]
HttpError(#[from] HttpError),

/// Custom error.
#[error("{0}")]
Custom(#[source] Box<dyn StdError + Send + Sync + 'static>),
Expand Down Expand Up @@ -67,4 +71,42 @@ impl TransportErrorKind {
pub const fn pubsub_unavailable() -> TransportError {
RpcError::Transport(Self::PubsubUnavailable)
}

/// Instantiate a new `TrasnportError::HttpError`.
pub const fn http_error(status: u16, body: String) -> TransportError {
RpcError::Transport(Self::HttpError(HttpError { status, body }))
}

/// Analyzes the [TransportErrorKind] and decides if the request should be retried based on the
/// variant.
pub fn is_retry_err(&self) -> bool {
match self {
// Missing batch response errors can be retried.
Self::MissingBatchResponse(_) => true,
Self::HttpError(http_err) => http_err.is_rate_limit_err(),
Self::Custom(err) => {
let msg = err.to_string();
msg.contains("429 Too Many Requests")
}
_ => false,
}
}
}

/// Type for holding HTTP errors such as 429 rate limit error.
#[derive(Debug, thiserror::Error)]
#[error("HTTP error {status} with body: {body}")]
pub struct HttpError {
pub status: u16,
pub body: String,
}

impl HttpError {
/// Checks the `status` to determine whether the request should be retried.
pub const fn is_rate_limit_err(&self) -> bool {
if self.status == 429 {
return true;
}
false
}
}

0 comments on commit cfb8df7

Please sign in to comment.