Skip to content

fix(error): use status.code instead of error_code for Milvus > 2.3 compatibility#105

Open
marlon-costa-dc wants to merge 1 commit into
milvus-io:mainfrom
marlon-costa-dc:fix/error-handling-status-code
Open

fix(error): use status.code instead of error_code for Milvus > 2.3 compatibility#105
marlon-costa-dc wants to merge 1 commit into
milvus-io:mainfrom
marlon-costa-dc:fix/error-handling-status-code

Conversation

@marlon-costa-dc
Copy link
Copy Markdown

Summary

  • Milvus server versions > 2.3 use status.code instead of status.error_code.
  • This PR updates error.rs and utils.rs to map status.code to ErrorCode properly.
  • Falls back to UnexpectedError with the original code and reason if the code is unknown.

@sre-ci-robot
Copy link
Copy Markdown
Collaborator

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: marlon-costa-dc
To complete the pull request process, please assign yah01 after the PR has been reviewed.
You can assign the PR to them by writing /assign @yah01 in a comment when ready.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@mergify
Copy link
Copy Markdown

mergify Bot commented Feb 25, 2026

@marlon-costa-dc Thanks for your contribution. Please submit with DCO, see the contributing guide https://github.com/milvus-io/milvus/blob/master/CONTRIBUTING.md#developer-certificate-of-origin-dco.

@mergify mergify Bot added the needs-dco label Feb 25, 2026
@mergify
Copy link
Copy Markdown

mergify Bot commented Feb 25, 2026

@marlon-costa-dc Please associate the related issue to the body of your Pull Request. (eg. “issue: #187”)

Comment thread src/utils.rs
"unknown error code {}",
status.error_code
))),
match ErrorCode::try_from(status.code) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR completely switches from status.error_code to status.code, but Milvus servers < 2.3 never populate status.code (protobuf default = 0 = Success). Any real error from an older server will be misclassified as Success and silently swallowed — the exact inverse of the bug this PR fixes.

The vendored proto confirms code is field tag 3 (new) vs error_code tag 1 (deprecated but present). pymilvus handles this by checking both: if status.code != 0 or status.error_code != 0.

Fix: read status.code first; when it is 0, fall back to status.error_code. Apply the same logic in error.rs From<Status>.

Comment thread src/error.rs
impl From<Status> for Error {
fn from(s: Status) -> Self {
Error::Server(ErrorCode::from_i32(s.error_code).unwrap(), s.reason)
let code = ErrorCode::try_from(s.code).unwrap_or(ErrorCode::UnexpectedError);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The From<Status> impl reads only s.code, so for Milvus < 2.3 servers it will produce Error::Server(Success, …) for genuine errors. This is the same compatibility regression as in utils.rs and needs the same code-then-error_code fallback.

Comment thread src/error.rs
impl From<Status> for Error {
fn from(s: Status) -> Self {
Error::Server(ErrorCode::from_i32(s.error_code).unwrap(), s.reason)
let code = ErrorCode::try_from(s.code).unwrap_or(ErrorCode::UnexpectedError);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Milvus >= 2.3 writes new-framework error codes into status.code (e.g. 100 = collection not found, 700 = index not found). These values do not match the old ErrorCode enum variants. ErrorCode::try_from(status.code) therefore maps to the wrong variant or falls through to UnexpectedError, losing the specific error type. Impact is limited because reason still carries the correct text, but any user code that pattern-matches on ErrorCode will hit the wrong arm.

Comment thread src/utils.rs
status.error_code
))),
match ErrorCode::try_from(status.code) {
Ok(ErrorCode::Success) => Ok(()),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

status_to_result() and From<Status> for Error are the global error gateway for every RPC call, yet there are no unit tests covering them. At minimum, tests should cover: code = 0 (success), code = known non-zero, code = unknown value (try_from failure), and the compatibility branch code = 0 && error_code != 0.

@mergify mergify Bot added the ci-passed label Apr 30, 2026
Comment thread src/utils.rs
match ErrorCode::try_from(status.code) {
Ok(ErrorCode::Success) => Ok(()),
Ok(_) => Err(Error::from(status)),
Err(_) => Err(Error::Server(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Err(_) branch in status_to_result() (lines 32-35) manually constructs Error::Server(UnexpectedError, …), duplicating the same fallback already in From<Status> (error.rs lines 78-83). This creates two independent maintenance points. The Err(_) branch can simply delegate to Err(Error::from(status)).

@yhmo yhmo force-pushed the fix/error-handling-status-code branch from 53637b8 to add40bc Compare April 30, 2026 10:33
Copilot AI review requested due to automatic review settings May 6, 2026 04:06
@yhmo yhmo force-pushed the fix/error-handling-status-code branch from add40bc to 12fda7f Compare May 6, 2026 04:06
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates Milvus Status error handling to be compatible with Milvus server versions > 2.3 by interpreting status.code (instead of the deprecated status.error_code) when mapping server responses into the SDK’s Error type.

Changes:

  • Updated status_to_result to interpret Status.code via ErrorCode conversion and preserve unknown numeric codes in the error message.
  • Updated From<Status> for Error to derive ErrorCode from Status.code, falling back to UnexpectedError for unknown codes while retaining the original numeric code in the reason string.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/utils.rs Switches status success/error detection to use Status.code and formats unknown codes into the returned error.
src/error.rs Switches Status -> Error conversion to map from Status.code and preserve unknown numeric codes in the reason text.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/utils.rs
Comment on lines +29 to +35
match ErrorCode::try_from(status.code) {
Ok(ErrorCode::Success) => Ok(()),
Ok(_) => Err(Error::from(status)),
Err(_) => Err(Error::Server(
ErrorCode::UnexpectedError,
format!("{} (code {})", status.reason, status.code),
)),
Comment thread src/error.rs
Comment on lines +78 to 85
let code = ErrorCode::try_from(s.code).unwrap_or(ErrorCode::UnexpectedError);
let reason = if code == ErrorCode::UnexpectedError && s.code != code as i32 {
format!("{} (code {})", s.reason, s.code)
} else {
s.reason
};
Error::Server(code, reason)
}
@yhmo yhmo added the code-conflict Code conflict, cannot be merged label May 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants