Merge pull request #768 from fabro-sh/sandbox-errors-transient-infra

Classify sandbox state-change rejections as transient infra
This commit is contained in:
Bryan Helmkamp 2026-08-20 18:16:47 -04:00 • committed by GitHub
commit 6885ed40cb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -84,6 +84,8 @@ const TRANSIENT_INFRA_HINTS: &[&str] = &[
"cross-device link",
"invalid cross-device link",
"os error 18",
"state change in progress",
"sandbox stop still in progress",
];
const BUDGET_EXHAUSTED_HINTS: &[&str] = &[
@ -807,6 +809,18 @@ mod tests {
assert_eq!(err.failure_category(), FailureCategory::TransientInfra);
}
#[test]
fn engine_error_with_sandbox_state_change_cause_classifies_transient() {
let source = TestOuterError {
message: "Failed to start Daytona sandbox",
source: TestCause("Sandbox state change in progress"),
};
let err = Error::engine_with_source("Pipeline lifecycle operation failed", source);
assert_eq!(err.failure_category(), FailureCategory::TransientInfra);
assert!(err.is_retryable());
}
#[test]
fn handler_error_display() {
let err = Error::handler("LLM call failed");
@ -1281,7 +1295,7 @@ mod tests {
#[test]
fn transient_infra_hints_count() {
assert_eq!(TRANSIENT_INFRA_HINTS.len(), 38);
assert_eq!(TRANSIENT_INFRA_HINTS.len(), 40);
}
#[test]
@ -1450,6 +1464,25 @@ mod tests {
);
}
#[test]
fn classify_reason_sandbox_state_change_in_progress() {
assert_eq!(
classify_failure_reason(
"Pipeline lifecycle operation failed: failed to activate sandbox after node \
attempt survey: Failed to start Daytona sandbox: Sandbox state change in progress"
),
FailureCategory::TransientInfra
);
}
#[test]
fn classify_reason_sandbox_stop_still_in_progress() {
assert_eq!(
classify_failure_reason("Daytona sandbox stop still in progress after 120s"),
FailureCategory::TransientInfra
);
}
#[test]
fn classify_reason_500() {
assert_eq!(