From a623c50e9c3d8ab25643ce2f660fe29a2ca5dc8c Mon Sep 17 00:00:00 2001 From: Raphael C Date: Sun, 28 Aug 2022 21:49:14 +0200 Subject: [PATCH] Limitation: display and handle client error (#280) * feat(limitation): display and handle client error * feat(limitation): handle other count errors * feat: add middleware errors catch changes to changelog Co-authored-by: Rob Ede --- actix-limitation/CHANGES.md | 1 + actix-limitation/src/middleware.rs | 32 ++++++++++++++++++++++++------ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/actix-limitation/CHANGES.md b/actix-limitation/CHANGES.md index 269ebb7ff..73a7b4092 100644 --- a/actix-limitation/CHANGES.md +++ b/actix-limitation/CHANGES.md @@ -3,6 +3,7 @@ ## Unreleased - 2022-xx-xx - Implement `Default` for `RateLimiter`. - `RateLimiter` is marked `#[non_exhaustive]`; use `RateLimiter::default()` instead. +- In the middleware errors from the count function are matched and respond with `INTERNAL_SERVER_ERROR` if it's an unexpected error, instead of the default `TOO_MANY_REQUESTS`. - Minimum supported Rust version (MSRV) is now 1.59 due to transitive `time` dependency. diff --git a/actix-limitation/src/middleware.rs b/actix-limitation/src/middleware.rs index ab1453ee3..d387e6d62 100644 --- a/actix-limitation/src/middleware.rs +++ b/actix-limitation/src/middleware.rs @@ -9,7 +9,7 @@ use actix_web::{ web, Error, HttpResponse, }; -use crate::Limiter; +use crate::{Error as LimitationError, Limiter}; /// Rate limit middleware. #[derive(Debug, Default)] @@ -86,12 +86,32 @@ where Box::pin(async move { let status = limiter.count(key.to_string()).await; - if status.is_err() { - log::warn!("Rate limit exceed error for {}", key); + if let Err(err) = status { + match err { + LimitationError::LimitExceeded(_) => { + log::warn!("Rate limit exceed error for {}", key); - Ok(req.into_response( - HttpResponse::new(StatusCode::TOO_MANY_REQUESTS).map_into_right_body(), - )) + Ok(req.into_response( + HttpResponse::new(StatusCode::TOO_MANY_REQUESTS).map_into_right_body(), + )) + } + LimitationError::Client(e) => { + log::error!("Client request failed, redis error: {}", e); + + Ok(req.into_response( + HttpResponse::new(StatusCode::INTERNAL_SERVER_ERROR) + .map_into_right_body(), + )) + } + _ => { + log::error!("Count failed: {}", err); + + Ok(req.into_response( + HttpResponse::new(StatusCode::INTERNAL_SERVER_ERROR) + .map_into_right_body(), + )) + } + } } else { service .call(req)