Sanitize history notes backend errors (#41235)

## What changed

Return consistent `Unable to perform operation:` messages for provider,
authentication, request construction, transport, and response parsing failures.
Do not include the underlying error details in these user-facing messages.

GitOrigin-RevId: c23fe7713f9d61e5f013ef217e1c0bdc2b824d83
This commit is contained in:
pmccrary-oai authored and copyberry committed 2026-08-28 00:48:44 +00:00
1 parent dc031d4bc7
commit f1bb4c168d
1 file changed
+20 -19
+20 -19
View File
@@ -14,6 +14,7 @@ use serde_json::json;
const HISTORY_NOTES_BACKEND_TIMEOUT: Duration = Duration::from_secs(35); const HISTORY_NOTES_BACKEND_TIMEOUT: Duration = Duration::from_secs(35);
const ENCRYPTED_TOOL_ARGUMENTS_HEADER: &str = "x-openai-encrypted-tool-arguments"; const ENCRYPTED_TOOL_ARGUMENTS_HEADER: &str = "x-openai-encrypted-tool-arguments";
const TOOL_OUTPUT_TRUNCATION_POLICY_HEADER: &str = "x-openai-tool-output-truncation-policy"; const TOOL_OUTPUT_TRUNCATION_POLICY_HEADER: &str = "x-openai-tool-output-truncation-policy";
const OPERATION_ERROR_PREFIX: &str = "Unable to perform operation:";
#[derive(Clone)] #[derive(Clone)]
pub(crate) struct HistoryNotesBackend { pub(crate) struct HistoryNotesBackend {
@@ -44,23 +45,24 @@ impl HistoryNotesBackend {
}), }),
); );
let provider = let provider = self.provider.api_provider().await.map_err(|_| {
self.provider.api_provider().await.map_err(|error| { format!("{OPERATION_ERROR_PREFIX} Could not resolve the backend provider.")
format!("History backend provider could not be resolved: {error}") })?;
})?; let auth = self.provider.api_auth().await.map_err(|_| {
let auth = self format!("{OPERATION_ERROR_PREFIX} Could not resolve backend authentication.")
.provider })?;
.api_auth()
.await
.map_err(|error| format!("History backend auth could not be resolved: {error}"))?;
let mut request = provider.build_request(Method::POST, path); let mut request = provider.build_request(Method::POST, path);
let encoded_truncation_policy = serde_json::to_string(&truncation_policy) let encoded_truncation_policy =
.map_err(|error| format!("Could not encode tool output truncation policy: {error}"))?; serde_json::to_string(&truncation_policy).map_err(|_| {
format!("{OPERATION_ERROR_PREFIX} Could not encode the output truncation policy.")
})?;
request.headers.insert( request.headers.insert(
TOOL_OUTPUT_TRUNCATION_POLICY_HEADER, TOOL_OUTPUT_TRUNCATION_POLICY_HEADER,
HeaderValue::from_str(&encoded_truncation_policy).map_err(|error| { HeaderValue::from_str(&encoded_truncation_policy).map_err(|_| {
format!("Invalid tool output truncation policy header: {error}") format!(
"{OPERATION_ERROR_PREFIX} Could not construct the output truncation policy header."
)
})?, })?,
); );
if matches!( if matches!(
@@ -77,17 +79,16 @@ impl HistoryNotesBackend {
} }
request.body = Some(RequestBody::Json(arguments)); request.body = Some(RequestBody::Json(arguments));
request.timeout = Some(HISTORY_NOTES_BACKEND_TIMEOUT); request.timeout = Some(HISTORY_NOTES_BACKEND_TIMEOUT);
let request = auth let request = auth.apply_auth(request).await.map_err(|_| {
.apply_auth(request) format!("{OPERATION_ERROR_PREFIX} Could not apply backend authentication.")
.await })?;
.map_err(|error| format!("History backend auth failed: {error}"))?;
let response = ReqwestTransport::from_http_client(create_client()) let response = ReqwestTransport::from_http_client(create_client())
.execute(request) .execute(request)
.await .await
.map_err(|error| format!("History backend request failed: {error}"))?; .map_err(|_| format!("{OPERATION_ERROR_PREFIX} The backend request failed."))?;
serde_json::from_slice(&response.body) serde_json::from_slice(&response.body)
.map_err(|error| format!("History backend returned invalid JSON: {error}")) .map_err(|_| format!("{OPERATION_ERROR_PREFIX} The backend returned invalid JSON."))
} }
} }