fix: preserve workdir failure diagnostics across transport

This commit is contained in:
2026-10-21 01:22:04 +09:00
parent 4ef7b03651
commit 1b6d4dbfd8
20 changed files with 440 additions and 29 deletions
+11
View File
@@ -2146,6 +2146,7 @@ impl RuntimeHttpWorkdirError {
Self {
status,
payload: WorkdirTransportError {
failure_reason: None,
denial_reason: None,
code,
message: message.into(),
@@ -2214,6 +2215,16 @@ impl From<workdir::WorkdirError> for RuntimeHttpWorkdirError {
impl IntoResponse for RuntimeHttpWorkdirError {
fn into_response(self) -> Response {
if let Some(reason) = self.payload.failure_reason {
tracing::warn!(
target: "worker_runtime::workdir",
event = "workdir_provider_failure",
status = self.status.as_u16(),
code = self.payload.code.as_str(),
failure_reason = reason.as_str(),
"Workdir provider operation failed"
);
}
(self.status, Json(self.payload)).into_response()
}
}
@@ -156,6 +156,42 @@ impl Harness {
}
}
#[tokio::test]
async fn real_http_closed_session_retains_failure_reason() {
let harness = Harness::new().await;
let handle = harness
.remote
.start_command(CommandRequest {
transport_byte_budget: 1024,
command: "printf done".into(),
timeout_secs: 5,
cwd: WorkdirPath::root(),
tool_call_id: None,
})
.await
.unwrap();
// Keep the HTTP session identity registered, but close the underlying provider.
harness.session.close().await.unwrap();
let error = harness
.remote
.command_output(CommandOutputRequest {
handle,
cursor: 0,
limit: 16,
wait: true,
})
.await
.unwrap_err();
assert_eq!(
error.failure_reason(),
Some(workdir::WorkdirFailureReason::SessionClosed)
);
assert!(matches!(
error.classification_source(),
workdir::WorkdirError::Unavailable(_)
));
}
#[tokio::test]
async fn real_http_command_pages_preserve_binary_streams_replay_and_nonzero_exit() {
tokio::time::timeout(Duration::from_secs(20), async {