From b1580c98f65bfceab6b009ecc55ff046d1e18a33 Mon Sep 17 00:00:00 2001 From: Yingwen Date: Mon, 20 Jul 2026 14:48:49 +0800 Subject: [PATCH] fix: display codes in metasrv client errors (#8558) * fix: display codes in metasrv client errors Signed-off-by: evenyag * fix: normalize meta client errors in sqlness Signed-off-by: evenyag --------- Signed-off-by: evenyag --- src/meta-client/src/error.rs | 2 +- tests/runner/src/formatter.rs | 61 +++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/meta-client/src/error.rs b/src/meta-client/src/error.rs index 917559fffb..d227896e34 100644 --- a/src/meta-client/src/error.rs +++ b/src/meta-client/src/error.rs @@ -29,7 +29,7 @@ pub enum Error { location: Location, }, - #[snafu(display("{}", msg))] + #[snafu(display("{}, code: {}, tonic code: {}", msg, code, tonic_code))] MetaServer { code: StatusCode, msg: String, diff --git a/tests/runner/src/formatter.rs b/tests/runner/src/formatter.rs index a379ad3244..0ae3b5ab20 100644 --- a/tests/runner/src/formatter.rs +++ b/tests/runner/src/formatter.rs @@ -40,6 +40,7 @@ impl Display for ErrorFormatter { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let status_code = self.0.status_code(); let root_cause = self.0.output_msg(); + let root_cause = normalize_meta_client_error(&root_cause, status_code); write!( f, "Error: {}({status_code}), {root_cause}", @@ -48,6 +49,17 @@ impl Display for ErrorFormatter { } } +fn normalize_meta_client_error( + root_cause: &str, + status_code: common_error::status_code::StatusCode, +) -> &str { + let details_prefix = format!(", code: {status_code}, tonic code: "); + match root_cause.rsplit_once(&details_prefix) { + Some((message, tonic_code)) if !tonic_code.is_empty() => message, + _ => root_cause, + } +} + /// A formatter for [`Output`]. pub struct OutputFormatter(Output); @@ -214,3 +226,52 @@ pub fn build_recordbatches_from_mysql_rows(rows: &[MySqlRow]) -> RecordBatches { RecordBatches::try_from_columns(schema, columns) .expect("Failed to construct recordbatches from columns. Please check the schema.") } + +#[cfg(test)] +mod tests { + use common_error::ext::PlainError; + use common_error::status_code::StatusCode; + + use super::*; + + #[test] + fn test_normalize_meta_client_error() { + let error = PlainError::new( + "Invalid options, code: InvalidArguments, tonic code: Client specified an invalid argument" + .to_string(), + StatusCode::InvalidArguments, + ); + + assert_eq!( + "Error: 1004(InvalidArguments), Invalid options", + ErrorFormatter::from(error).to_string() + ); + } + + #[test] + fn test_preserve_regular_error() { + let error = PlainError::new( + "Invalid options without transport details".to_string(), + StatusCode::InvalidArguments, + ); + + assert_eq!( + "Error: 1004(InvalidArguments), Invalid options without transport details", + ErrorFormatter::from(error).to_string() + ); + } + + #[test] + fn test_preserve_error_with_mismatched_code() { + let error = PlainError::new( + "Invalid options, code: Unsupported, tonic code: Operation is not supported" + .to_string(), + StatusCode::InvalidArguments, + ); + + assert_eq!( + "Error: 1004(InvalidArguments), Invalid options, code: Unsupported, tonic code: Operation is not supported", + ErrorFormatter::from(error).to_string() + ); + } +}