From 15c21baf2022c31ca416f3713570ea202e82359a Mon Sep 17 00:00:00 2001 From: Shanu Date: Tue, 19 May 2026 14:37:18 +0530 Subject: [PATCH 1/3] fix(embeddings):route embedding API errors through expected-error classifier to improve observability --- src/openhuman/embeddings/openai.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/openhuman/embeddings/openai.rs b/src/openhuman/embeddings/openai.rs index 1d74e49a52..4e0b5934ea 100644 --- a/src/openhuman/embeddings/openai.rs +++ b/src/openhuman/embeddings/openai.rs @@ -129,7 +129,11 @@ impl EmbeddingProvider for OpenAiEmbedding { "[openai] embed error: status={status}, body={text}" ); let message = format!("Embedding API error {status}: {text}"); - crate::core::observability::report_error( + // Route through the expected-error classifier so user-state + // conditions (budget exhausted / insufficient credits, missing + // API key, transient upstream HTTP) are demoted to info/warn + // breadcrumbs instead of spawning Sentry error events. + crate::core::observability::report_error_or_expected( message.as_str(), "embeddings", "openai_embed", From 06783c5a6ce37de4d0f855f0bc0c9cff286f429d Mon Sep 17 00:00:00 2001 From: Shanu Date: Tue, 19 May 2026 14:37:39 +0530 Subject: [PATCH 2/3] test(embeddings): add test for handling budget-exhausted errors in embedding API --- src/openhuman/embeddings/openai_tests.rs | 26 ++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/openhuman/embeddings/openai_tests.rs b/src/openhuman/embeddings/openai_tests.rs index 527bdb9fc6..06c41a4e69 100644 --- a/src/openhuman/embeddings/openai_tests.rs +++ b/src/openhuman/embeddings/openai_tests.rs @@ -224,6 +224,32 @@ async fn embed_server_error() { assert!(msg.contains("rate limited"), "body: {msg}"); } +#[tokio::test] +async fn embed_budget_exhausted_400_still_errors() { + // OPENHUMAN-TAURI-JM: the backend returns HTTP 400 with a budget-exhausted + // body when the user is out of credits. The provider must still surface + // an `Err` to the caller (so the calling pipeline can short-circuit), but + // the diagnostic emit site must route through `report_error_or_expected` + // so the message is classified as `BudgetExhausted` and demoted rather + // than spawning a Sentry error event for every embed call. + let app = Router::new().route( + "/v1/embeddings", + post(|| async { + ( + StatusCode::BAD_REQUEST, + r#"{"success":false,"error":"Budget exceeded — add credits to continue"}"#, + ) + }), + ); + let url = start_mock(app).await; + let p = OpenAiEmbedding::new(&url, "k", "m", 1); + + let err = p.embed(&["hi"]).await.unwrap_err(); + let msg = err.to_string(); + assert!(msg.contains("400"), "status: {msg}"); + assert!(msg.contains("Budget exceeded"), "body: {msg}"); +} + #[tokio::test] async fn embed_missing_data_field() { let app = Router::new().route( From 81ee0ef15cf8ae7ff16e3fac434855541e5763ea Mon Sep 17 00:00:00 2001 From: Shanu Date: Tue, 19 May 2026 14:38:38 +0530 Subject: [PATCH 3/3] fix(embeddings): correct comment formatting in error reporting for embedding API --- src/openhuman/embeddings/openai.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openhuman/embeddings/openai.rs b/src/openhuman/embeddings/openai.rs index 4e0b5934ea..1b7eb99359 100644 --- a/src/openhuman/embeddings/openai.rs +++ b/src/openhuman/embeddings/openai.rs @@ -132,7 +132,7 @@ impl EmbeddingProvider for OpenAiEmbedding { // Route through the expected-error classifier so user-state // conditions (budget exhausted / insufficient credits, missing // API key, transient upstream HTTP) are demoted to info/warn - // breadcrumbs instead of spawning Sentry error events. + // breadcrumbs instead of spawning Sentry error events. crate::core::observability::report_error_or_expected( message.as_str(), "embeddings",