From a15b5dbf5896711fbed10bd03a2ee587742718c2 Mon Sep 17 00:00:00 2001 From: weli Date: Mon, 27 Apr 2026 00:32:09 +0800 Subject: [PATCH] fix(htyproc): convert task_result values to string in wrap_common_task; preserve body text in parse_hty_response on JSON error --- htyproc/src/tasks/pipelines.rs | 35 +++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/htyproc/src/tasks/pipelines.rs b/htyproc/src/tasks/pipelines.rs index 0c8e8b3..71aa59d 100644 --- a/htyproc/src/tasks/pipelines.rs +++ b/htyproc/src/tasks/pipelines.rs @@ -585,10 +585,13 @@ fn wrap_ts_common_task(req: &ReqTask) -> Value { } fn wrap_common_task(result: &CommonTaskResult, task_type: &str) -> Value { - let task_result = result - .task_result - .as_ref() - .map(|m| serde_json::Value::Object(m.iter().map(|(k, v)| (k.clone(), v.clone())).collect())); + let task_result = result.task_result.as_ref().map(|m| { + serde_json::Value::Object( + m.iter() + .map(|(k, v)| (k.clone(), json_val_to_string(v))) + .collect(), + ) + }); json!({ "task_id": result.task_id, "task_type": task_type, @@ -601,7 +604,19 @@ fn wrap_common_task(result: &CommonTaskResult, task_type: &str) -> Value { async fn parse_hty_response(resp: reqwest::Response) -> anyhow::Result { let status = resp.status(); - let v: Value = resp.json().await?; + let body_text = resp.text().await?; + let v: Value = match serde_json::from_str(&body_text) { + Ok(v) => v, + Err(e) => { + let snippet = body_text.chars().take(500).collect::(); + anyhow::bail!( + "parse_hty_response: bad JSON (status={}, body_snippet={:?}): {}", + status, + snippet, + e, + ); + } + }; if !status.is_success() { tracing::debug!( http_status = %status, @@ -699,6 +714,16 @@ fn json_value_as_string(v: &Value) -> Option { } } +fn json_val_to_string(v: &Value) -> Value { + match v { + Value::String(s) => Value::String(s.clone()), + Value::Number(n) => Value::String(n.to_string()), + Value::Bool(b) => Value::String(b.to_string()), + Value::Null => Value::Null, + other => Value::String(other.to_string()), + } +} + fn extract_created_hty_resource_id(d: &Value) -> Option { json_value_as_string(d) .or_else(|| d.get("hty_resource_id").and_then(json_value_as_string))