From 0b847f95d650bdd77f7c8eeb4df6e5983cd894d5 Mon Sep 17 00:00:00 2001 From: tprevot Date: Thu, 13 Aug 2026 16:57:40 +0200 Subject: [PATCH 1/2] fix: improve error details --- src/error.rs | 9 +++++++++ src/flagsmith/mod.rs | 8 +++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/error.rs b/src/error.rs index c3a2a13..3cba725 100644 --- a/src/error.rs +++ b/src/error.rs @@ -2,6 +2,8 @@ use std::convert::From; use std::error; use std::fmt; +use reqwest::StatusCode; + /// Wraps several types of errors. #[derive(Debug)] pub struct Error { @@ -22,6 +24,13 @@ impl Error{ msg } } + + pub fn http(status: StatusCode, body: String) -> Error { + Error { + kind: ErrorKind::FlagsmithAPIError, + msg: format!("HTTP Api error: {status}, {body}") + } + } } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { diff --git a/src/flagsmith/mod.rs b/src/flagsmith/mod.rs index 3ca80b8..dd569de 100644 --- a/src/flagsmith/mod.rs +++ b/src/flagsmith/mod.rs @@ -434,13 +434,11 @@ fn get_json_response( request = request.body(body.unwrap()); }; let response = request.send()?; - if response.status().is_success() { + let status = response.status(); + if status.is_success() { return Ok(response.json()?); } else { - return Err(error::Error::new( - error::ErrorKind::FlagsmithAPIError, - response.text()?, - )); + return Err(error::Error::http(status, response.text()?)); } } From b260f3f34d469beec8e6dd58408750401d1a5e16 Mon Sep 17 00:00:00 2001 From: tprevot Date: Tue, 18 Aug 2026 09:59:30 +0200 Subject: [PATCH 2/2] fix: add tests --- src/error.rs | 23 +++++++++++++++++++++++ tests/integration_test.rs | 7 ++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/error.rs b/src/error.rs index 3cba725..549414a 100644 --- a/src/error.rs +++ b/src/error.rs @@ -60,3 +60,26 @@ impl From for Error { Error::new(ErrorKind::FlagsmithAPIError, e.to_string()) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_http_error_includes_status_and_body() { + let error = Error::http( + StatusCode::BAD_GATEWAY, + "{\"detail\":\"upstream unavailable\"}".to_string(), + ); + + assert_eq!(error.kind, ErrorKind::FlagsmithAPIError); + assert_eq!( + error.msg, + "HTTP Api error: 502 Bad Gateway, {\"detail\":\"upstream unavailable\"}" + ); + assert_eq!( + error.to_string(), + "Flagsmith API error: HTTP Api error: 502 Bad Gateway, {\"detail\":\"upstream unavailable\"}" + ); + } +} diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 1beb975..0ff1c23 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -713,7 +713,8 @@ fn test_flagsmith_api_error_is_returned_if_something_goes_wrong_with_the_request when.method(GET) .path("/api/v1/flags/") .header("X-Environment-Key", ENVIRONMENT_KEY); - then.status(502).json_body({}); // returning 502 + then.status(502) + .json_body(serde_json::json!({"detail": "bad gateway"})); // returning 502 }); let url = mock_server.url("/api/v1/"); let flagsmith_options = FlagsmithOptions { @@ -724,7 +725,11 @@ fn test_flagsmith_api_error_is_returned_if_something_goes_wrong_with_the_request // When let err = flagsmith.get_environment_flags().err().unwrap(); + + // Then: the error carries the HTTP status and the response body assert_eq!(err.kind, flagsmith::error::ErrorKind::FlagsmithAPIError); + assert!(err.msg.contains("502 Bad Gateway"), "unexpected msg: {}", err.msg); + assert!(err.msg.contains("bad gateway"), "unexpected msg: {}", err.msg); } #[rstest]