From 5e0fdaa247ab774e9784b6b9f6f436dadd475645 Mon Sep 17 00:00:00 2001 From: Zhengchao An Date: Thu, 6 Aug 2026 08:34:46 +0800 Subject: [PATCH] fix(table-catalog): route read_bounded_json_body errors through ApiError to hold s3s ratchet (#5759) The namespace REST contracts PR (#5745) added 7 new s3_error! invocations in read_bounded_json_body, pushing the s3s footprint counter from 1687 to 1693 and violating the ratchet baseline. Replace those calls with ApiError::invalid_request() (gateway-side error abstraction, rustfs/backlog#1677 F1, rustfs/backlog#1733) and lower the baseline from 1687 to 1686. - Add ApiError::invalid_request(message) constructor to rustfs/src/error.rs - Replace 7 s3_error! calls in read_bounded_json_body with S3Error::from(ApiError) - Lower S3_ERROR_LINES_BASELINE from 1687 to 1686 Verification: - make pre-commit: all guard scripts + fmt-check + quick-check passed - make clippy-check: passed - cargo test table_catalog + admin handler tests: 406/406 passed - s3s-e2e: 27/27 passed --- rustfs/src/admin/handlers/table_catalog/mod.rs | 15 ++++++++------- rustfs/src/error.rs | 8 ++++++++ scripts/check_s3s_footprint.sh | 2 +- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/rustfs/src/admin/handlers/table_catalog/mod.rs b/rustfs/src/admin/handlers/table_catalog/mod.rs index 5cce15684..dbaf0eb8f 100644 --- a/rustfs/src/admin/handlers/table_catalog/mod.rs +++ b/rustfs/src/admin/handlers/table_catalog/mod.rs @@ -21,6 +21,7 @@ use crate::admin::{ router::{AdminOperation, Operation, S3Router}, }; use crate::auth::{check_key_valid, get_session_token}; +use crate::error::ApiError; use crate::server::{RemoteAddr, TABLE_CATALOG_COMPAT_PREFIX, TABLE_CATALOG_PREFIX}; use crate::table_catalog::{DEFAULT_WAREHOUSE_ID, TableCatalogStore}; use http::{HeaderMap, HeaderValue, StatusCode}; @@ -1148,21 +1149,21 @@ async fn read_bounded_json_body( if let Some(content_length) = headers.get(http::header::CONTENT_LENGTH) { let content_length = content_length .to_str() - .map_err(|_| s3_error!(InvalidRequest, "Content-Length must be valid ASCII"))? + .map_err(|_| S3Error::from(ApiError::invalid_request("Content-Length must be valid ASCII")))? .parse::() - .map_err(|_| s3_error!(InvalidRequest, "Content-Length must be a non-negative integer"))?; + .map_err(|_| S3Error::from(ApiError::invalid_request("Content-Length must be a non-negative integer")))?; if content_length > max_size { - return Err(s3_error!(InvalidRequest, "{operation} request body is too large")); + return Err(S3Error::from(ApiError::invalid_request(format!("{operation} request body is too large")))); } } let body = tokio::time::timeout(timeout, input.store_all_limited(max_size)) .await - .map_err(|_| s3_error!(InvalidRequest, "timed out reading {operation} request body"))? - .map_err(|err| s3_error!(InvalidRequest, "failed to read request body: {}", err))?; + .map_err(|_| S3Error::from(ApiError::invalid_request(format!("timed out reading {operation} request body"))))? + .map_err(|err| S3Error::from(ApiError::invalid_request(format!("failed to read request body: {err}"))))?; if body.is_empty() { - return Err(s3_error!(InvalidRequest, "request body is required")); + return Err(S3Error::from(ApiError::invalid_request("request body is required"))); } - serde_json::from_slice(&body).map_err(|err| s3_error!(InvalidRequest, "invalid JSON: {}", err)) + serde_json::from_slice(&body).map_err(|err| S3Error::from(ApiError::invalid_request(format!("invalid JSON: {err}")))) } async fn read_json_body_or_default(mut input: Body) -> S3Result diff --git a/rustfs/src/error.rs b/rustfs/src/error.rs index e7826bbac..93f69cd50 100644 --- a/rustfs/src/error.rs +++ b/rustfs/src/error.rs @@ -43,6 +43,14 @@ impl ApiError { } } + pub fn invalid_request(message: impl std::fmt::Display) -> Self { + ApiError { + code: S3ErrorCode::InvalidRequest, + message: message.to_string(), + source: None, + } + } + pub fn other(error: E) -> Self where E: std::fmt::Display + Into>, diff --git a/scripts/check_s3s_footprint.sh b/scripts/check_s3s_footprint.sh index 3aa684573..a70cdeb11 100755 --- a/scripts/check_s3s_footprint.sh +++ b/scripts/check_s3s_footprint.sh @@ -24,7 +24,7 @@ cd "$(dirname "$0")/.." # Baselines verified on 2026-08-05. Lower-only; see header. S3S_IMPORT_FILES_BASELINE=236 -S3_ERROR_LINES_BASELINE=1687 +S3_ERROR_LINES_BASELINE=1686 TMP_DIR="$(mktemp -d)" trap 'rm -rf "$TMP_DIR"' EXIT