runtime: normalize structured secret errors

This commit is contained in:
a.tolmachev
2026-04-19 21:25:28 +00:00
parent 899440fd8a
commit 5debf4dd05
7 changed files with 85 additions and 25 deletions
+22 -4
View File
@@ -395,7 +395,8 @@ impl PreparedRequest {
mapped
.get("request")
.ok_or_else(|| RuntimeError::InvalidPreparedRequest {
details: "mapped input must contain request root".to_owned(),
field: "request".to_owned(),
reason: "mapped input must contain request root".to_owned(),
})?;
Ok(Self {
@@ -460,7 +461,8 @@ fn read_string_map(
let Some(object) = value.as_object() else {
return Err(RuntimeError::InvalidPreparedRequest {
details: format!("{field_name} must be an object"),
field: field_name.to_owned(),
reason: "must be an object".to_owned(),
});
};
@@ -468,7 +470,10 @@ fn read_string_map(
.iter()
.map(|(key, value)| stringify_value(value).map(|value| (key.clone(), value)))
.collect::<Result<BTreeMap<_, _>, _>>()
.map_err(|details| RuntimeError::InvalidPreparedRequest { details })
.map_err(|reason| RuntimeError::InvalidPreparedRequest {
field: field_name.to_owned(),
reason,
})
}
fn stringify_value(value: &Value) -> Result<String, String> {
@@ -525,7 +530,7 @@ mod tests {
use tokio::net::TcpListener;
use tokio_tungstenite::accept_async;
use crate::{RuntimeError, RuntimeExecutor, RuntimeOperation};
use crate::{PreparedRequest, RuntimeError, RuntimeExecutor, RuntimeOperation};
fn timestamp(value: &str) -> OffsetDateTime {
OffsetDateTime::parse(value, &Rfc3339).unwrap()
@@ -638,6 +643,19 @@ mod tests {
assert!(matches!(error, RuntimeError::Schema(_)));
}
#[test]
fn rejects_missing_request_root_with_structured_error() {
let error = PreparedRequest::from_mapping_output(&json!({})).unwrap_err();
match error {
RuntimeError::InvalidPreparedRequest { field, reason } => {
assert_eq!(field, "request");
assert_eq!(reason, "mapped input must contain request root");
}
other => panic!("unexpected error: {other}"),
}
}
#[tokio::test]
async fn propagates_external_rest_errors() {
let base_url = spawn_runtime_server().await;