diff --git a/crates/forge_infra/src/http.rs b/crates/forge_infra/src/http.rs index 228cc902ef..aaa03c9d25 100644 --- a/crates/forge_infra/src/http.rs +++ b/crates/forge_infra/src/http.rs @@ -173,8 +173,11 @@ impl ForgeHttpInfra { .text() .await .unwrap_or_else(|_| "Unable to read response body".to_string()); - return Err(anyhow::anyhow!(error_body)) - .with_context(|| format_http_context(Some(status), method, url)); + return Err(anyhow::Error::from( + forge_app::dto::openai::Error::InvalidStatusCode(status.as_u16()), + )) + .context(error_body) + .with_context(|| format_http_context(Some(status), method, url)); } Ok(response) diff --git a/crates/forge_repo/src/provider/openai_responses/repository.rs b/crates/forge_repo/src/provider/openai_responses/repository.rs index d709972170..99fd725dc0 100644 --- a/crates/forge_repo/src/provider/openai_responses/repository.rs +++ b/crates/forge_repo/src/provider/openai_responses/repository.rs @@ -1568,7 +1568,7 @@ mod tests { let mut fixture = MockServer::new().await; let _mock = fixture - .mock_codex_responses_stream("/backend-api/codex/responses", vec![], 400) + .mock_codex_responses_stream("/backend-api/codex/responses", vec![], 429) .await; let codex_url = format!("{}/backend-api/codex/responses", fixture.url()); @@ -1593,8 +1593,10 @@ mod tests { let actual = provider_impl .chat(&ModelId::from("gpt-5.1-codex"), context) .await; + let actual = actual.err().expect("chat should fail with status error"); - assert!(actual.is_err()); + let expected = Some(429); + assert_eq!(retry::get_api_status_code(&actual), expected); Ok(()) }