Skip to content

Commit d7bba86

Browse files
committed
fix: improve status code extraction from API client error messages
Bug fix for index-out-of-bounds error when attempting to parse the status message string for status code and the delimiter "Status" is not found. extract_status_code_from_error returns None if the delimiter is not found or an invalid status code is given in the error message
1 parent c0d2f62 commit d7bba86

File tree

3 files changed

+17
-8
lines changed

3 files changed

+17
-8
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

agent/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ apiserver = { path = "../apiserver", version = "0.1.0", default-features = false
1414

1515
futures = { workspace = true }
1616
governor = { workspace = true }
17+
http = { workspace = true }
1718
lazy_static = { workspace = true }
1819
nonzero_ext = { workspace = true }
1920
tracing = { workspace = true }

agent/src/apiclient.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ pub(super) mod api {
110110
state::{InMemoryState, NotKeyed},
111111
Quota, RateLimiter,
112112
};
113+
use http::StatusCode;
113114
use lazy_static::lazy_static;
114115
use nonzero_ext::nonzero;
115116
use semver::Version;
@@ -124,7 +125,7 @@ pub(super) mod api {
124125
use tracing::{event, instrument, Level};
125126

126127
const API_CLIENT_BIN: &str = "apiclient";
127-
const UPDATE_API_BUSY_STATUSCODE: &str = "423";
128+
const UPDATE_API_BUSY_STATUSCODE: StatusCode = StatusCode::LOCKED;
128129
const ACTIVATE_UPDATES_URI: &str = "/actions/activate-update";
129130
const OS_URI: &str = "/os";
130131
const PREPARE_UPDATES_URI: &str = "/actions/prepare-update";
@@ -232,12 +233,15 @@ pub(super) mod api {
232233
/// Extract error statuscode from stderr string
233234
/// Error Example:
234235
/// "Failed POST request to '/actions/refresh-updates': Status 423 when POSTing /actions/refresh-updates: Update lock held\n"
235-
fn extract_status_code_from_error(error: &str) -> &str {
236-
let error_content_split_by_status: Vec<&str> = error.split("Status").collect();
237-
let error_content_split_by_whitespace: Vec<&str> = error_content_split_by_status[1]
236+
fn extract_status_code_from_error(error: &str) -> Option<StatusCode> {
237+
error
238+
.split("Status ")
239+
.nth(1)?
238240
.split_whitespace()
239-
.collect();
240-
error_content_split_by_whitespace[0]
241+
.next()?
242+
.parse::<u16>()
243+
.ok()
244+
.and_then(|code| StatusCode::from_u16(code).ok())
241245
}
242246

243247
/// Wait time between invoking the Bottlerocket API
@@ -294,7 +298,7 @@ pub(super) mod api {
294298
let error_statuscode = extract_status_code_from_error(&error_content);
295299

296300
match error_statuscode {
297-
UPDATE_API_BUSY_STATUSCODE => {
301+
Some(UPDATE_API_BUSY_STATUSCODE) => {
298302
event!(
299303
Level::DEBUG,
300304
"The lock for the update API is held by another process ..."
@@ -307,7 +311,10 @@ pub(super) mod api {
307311
apiclient_error::BadHttpResponseSnafu {
308312
args: args.clone(),
309313
error_content: &error_content,
310-
statuscode: error_statuscode,
314+
statuscode: error_statuscode.map_or_else(
315+
|| "None".to_string(),
316+
|s| s.as_u16().to_string(),
317+
),
311318
}
312319
.fail()
313320
}

0 commit comments

Comments
 (0)