From 2741f7b3c695c6ebde16916031cd46ea4fb8590d Mon Sep 17 00:00:00 2001 From: Evan Purkhiser Date: Fri, 20 Feb 2026 20:08:58 +0800 Subject: [PATCH 1/2] feat(uptime): remove built-in 2xx status code check Relies on assertions to validate responses instead of a hard-coded 2xx check. When no assertion is configured, any response is considered a success. Callers are expected to configure a status code assertion to validate the response code. Fixed [NEW-758](https://linear.app/getsentry/issue/NEW-758/remove-built-in-status-code-check-from-uptime-checker) --- src/checker.rs | 2 +- src/checker/reqwest_checker.rs | 36 ++++++++++++++++++++-------------- src/types/result.rs | 13 ------------ 3 files changed, 22 insertions(+), 29 deletions(-) diff --git a/src/checker.rs b/src/checker.rs index 94fb0653..b1c3b668 100644 --- a/src/checker.rs +++ b/src/checker.rs @@ -44,7 +44,7 @@ fn make_trace_header(config: &CheckConfig, trace_id: &Uuid, span_id: SpanId) -> /// which the check is being made. pub trait Checker: Send + Sync { /// Makes a request to a url to determine whether it is up. - /// Up is defined as returning a 2xx within a specific timeframe. + /// Up is defined as responding within a specific timeframe, optionally validated by assertions. fn check_url( &self, check: &ScheduledCheck, diff --git a/src/checker/reqwest_checker.rs b/src/checker/reqwest_checker.rs index 220904d9..8962eb4c 100644 --- a/src/checker/reqwest_checker.rs +++ b/src/checker/reqwest_checker.rs @@ -334,18 +334,11 @@ fn to_check_result( max_assertion_ops, region, ) - } else if r.status().is_success() { - Check::success() } else { - Check::code_failure(r.status()) + Check::success() } } else { - // TODO: rust 2024 allows let-chaining, so the enclosing if-statement can be - // folded into the the if let - match r.status().is_success() { - true => Check::success(), - false => Check::code_failure(r.status()), - } + Check::success() } } Err(e) => Check::other_failure(e.into()), @@ -510,7 +503,7 @@ fn to_errored_request_infos( impl Checker for ReqwestChecker { /// Makes a request to a url to determine whether it is up. - /// Up is defined as returning a 2xx within a specific timeframe, along with executing + /// Up is defined as responding within a specific timeframe, along with passing /// an optional user-defined assert that is specified by the user which can use /// the result json, status code, and response header values. #[tracing::instrument] @@ -889,7 +882,7 @@ mod tests { } #[tokio::test] - async fn test_simple_400() { + async fn test_simple_400_no_assertion() { let server = MockServer::start(); let checker = ReqwestChecker::new_internal( Options { @@ -916,14 +909,13 @@ mod tests { let check = ScheduledCheck::new_for_test(tick, config); let result = checker.check_url(&check, "us-west").await; - assert_eq!(result.status, CheckStatus::Failure); + // Without an assertion, a non-2xx response is still considered a success. + // Callers are expected to configure a status code assertion to validate the response. + assert_eq!(result.status, CheckStatus::Success); assert_eq!( result.request_info.and_then(|i| i.http_status_code), Some(400) ); - let reason = result.status_reason.unwrap(); - assert_eq!(reason.status_type, CheckStatusReasonType::Failure); - assert_eq!(reason.description, "Got non 2xx status: 400 Bad Request"); head_mock.assert(); } @@ -953,6 +945,13 @@ mod tests { let config = CheckConfig { url: server.url("/error").to_string(), + assertion: crate::assertions::Assertion { + root: crate::assertions::Op::StatusCodeCheck { + value: 500, + operator: crate::assertions::Comparison::NotEqual, + }, + } + .into(), ..Default::default() }; @@ -1007,6 +1006,13 @@ mod tests { let config = CheckConfig { url: server.url("/error").to_string(), + assertion: crate::assertions::Assertion { + root: crate::assertions::Op::StatusCodeCheck { + value: 500, + operator: crate::assertions::Comparison::NotEqual, + }, + } + .into(), ..Default::default() }; diff --git a/src/types/result.rs b/src/types/result.rs index 568b3913..1603d287 100644 --- a/src/types/result.rs +++ b/src/types/result.rs @@ -2,7 +2,6 @@ use crate::assertions::compiled; use crate::assertions::compiled::EvalPath; use crate::assertions::Assertion; use chrono::{DateTime, TimeDelta, Utc}; -use http::StatusCode; use hyper::rt::ConnectionStats; use hyper::stats::AbsoluteDuration; use hyper::stats::RequestStats; @@ -414,18 +413,6 @@ impl Check { } } - pub fn code_failure(status: StatusCode) -> Self { - Self { - result: CheckStatus::Failure, - reason: Some(CheckStatusReason { - status_type: CheckStatusReasonType::Failure, - description: format!("Got non 2xx status: {status}"), - details: None, - }), - assert_path: None, - } - } - pub fn other_failure(reason: CheckStatusReason) -> Self { Self { result: CheckStatus::Failure, From d8dd2acda8e5ed51c9da56656f76b30de601d006 Mon Sep 17 00:00:00 2001 From: "getsantry[bot]" <66042841+getsantry[bot]@users.noreply.github.com> Date: Fri, 20 Feb 2026 12:21:41 +0000 Subject: [PATCH 2/2] :hammer_and_wrench: apply pre-commit fixes --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 16784c57..cf9ca397 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4736,7 +4736,7 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "uptime-checker" -version = "26.1.0" +version = "26.2.0" dependencies = [ "anyhow", "associative-cache",