Description
There is a logic inconsistency in how network timeouts are classified between typed error handling and string-pattern matching in the transaction submission error classification.
File: app/solana/cmd/api/src/api/transaction/v1/service_impl.rs
Current Behavior
Typed error examination (lines 130-138) — correctly returns Indeterminate:
// Network transport errors - connectivity, timeouts, HTTP issues (INDETERMINATE)
ClientErrorKind::Io(_) => SubmissionResult::Indeterminate,
ClientErrorKind::Reqwest(reqwest_error) => {
if reqwest_error.is_timeout() {
// Timeouts are especially dangerous - transaction might have been sent
}
// Connection/request failures - also indeterminate
SubmissionResult::Indeterminate
}
String-pattern matching in classify_by_message (lines 286-289) — incorrectly returns FailedNetworkError:
} else if error_str.contains("network")
|| error_str.contains("connection")
|| error_str.contains("timeout")
{
SubmissionResult::FailedNetworkError
}
Expected Behavior
Both code paths should return SubmissionResult::Indeterminate when a timeout is detected. The string "timeout" in classify_by_message should map to Indeterminate, consistent with the typed logic.
Why This Matters
If a timeout occurs, we cannot guarantee the transaction wasn't already processed by the cluster. Labeling it as a FailedNetworkError may trigger unsafe retry logic in downstream consumers that assumes the transaction never reached the leader, potentially causing duplicate submissions.
Proposed Changes
-
Immediate fix: Update classify_by_message to return Indeterminate when a timeout string is detected, aligning with the typed error logic.
-
Refactor opportunity: Evaluate whether classify_by_message can be deprecated entirely in favor of expanded typed error handling. The string-matching approach is fragile — it breaks if Solana node error message formats change — while the typed path (lines 106-158) already covers 95%+ of real-world cases. Currently classify_by_message is only reachable via ClientErrorKind::Custom(_) (line 156).
Description
There is a logic inconsistency in how network timeouts are classified between typed error handling and string-pattern matching in the transaction submission error classification.
File:
app/solana/cmd/api/src/api/transaction/v1/service_impl.rsCurrent Behavior
Typed error examination (lines 130-138) — correctly returns
Indeterminate:String-pattern matching in
classify_by_message(lines 286-289) — incorrectly returnsFailedNetworkError:Expected Behavior
Both code paths should return
SubmissionResult::Indeterminatewhen a timeout is detected. The string"timeout"inclassify_by_messageshould map toIndeterminate, consistent with the typed logic.Why This Matters
If a timeout occurs, we cannot guarantee the transaction wasn't already processed by the cluster. Labeling it as a
FailedNetworkErrormay trigger unsafe retry logic in downstream consumers that assumes the transaction never reached the leader, potentially causing duplicate submissions.Proposed Changes
Immediate fix: Update
classify_by_messageto returnIndeterminatewhen a timeout string is detected, aligning with the typed error logic.Refactor opportunity: Evaluate whether
classify_by_messagecan be deprecated entirely in favor of expanded typed error handling. The string-matching approach is fragile — it breaks if Solana node error message formats change — while the typed path (lines 106-158) already covers 95%+ of real-world cases. Currentlyclassify_by_messageis only reachable viaClientErrorKind::Custom(_)(line 156).