From f21ba9e2c6789fadd3a59f88e0eb1ff4e1f919db Mon Sep 17 00:00:00 2001 From: Umesh Yadav <23421535+imumesh18@users.noreply.github.com> Date: Fri, 25 Jul 2025 19:06:43 +0530 Subject: [PATCH] lmstudio: Propagate actual error message from server (#34538) Discovered in this issue: #34513 Previously, we were propagating deserialization errors to users when using LMStudio, instead of the actual error message sent from the LMStudio server. This change will help users understand why their request failed while streaming responses. Release Notes: - lmsudio: Display specific backend error messaging on failure rather than generic ones --------- Signed-off-by: Umesh Yadav Co-authored-by: Peter Tripp --- crates/lmstudio/src/lmstudio.rs | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/crates/lmstudio/src/lmstudio.rs b/crates/lmstudio/src/lmstudio.rs index a5477994ff..43c78115cd 100644 --- a/crates/lmstudio/src/lmstudio.rs +++ b/crates/lmstudio/src/lmstudio.rs @@ -1,4 +1,4 @@ -use anyhow::{Context as _, Result}; +use anyhow::{Context as _, Result, anyhow}; use futures::{AsyncBufReadExt, AsyncReadExt, StreamExt, io::BufReader, stream::BoxStream}; use http_client::{AsyncBody, HttpClient, Method, Request as HttpRequest, http}; use serde::{Deserialize, Serialize}; @@ -275,11 +275,16 @@ impl Capabilities { } } +#[derive(Serialize, Deserialize, Debug)] +pub struct LmStudioError { + pub message: String, +} + #[derive(Serialize, Deserialize, Debug)] #[serde(untagged)] pub enum ResponseStreamResult { Ok(ResponseStreamEvent), - Err { error: String }, + Err { error: LmStudioError }, } #[derive(Serialize, Deserialize, Debug)] @@ -392,7 +397,6 @@ pub async fn stream_chat_completion( let mut response = client.send(request).await?; if response.status().is_success() { let reader = BufReader::new(response.into_body()); - Ok(reader .lines() .filter_map(|line| async move { @@ -402,18 +406,16 @@ pub async fn stream_chat_completion( if line == "[DONE]" { None } else { - let result = serde_json::from_str(&line) - .context("Unable to parse chat completions response"); - if let Err(ref e) = result { - eprintln!("Error parsing line: {e}\nLine content: '{line}'"); + match serde_json::from_str(line) { + Ok(ResponseStreamResult::Ok(response)) => Some(Ok(response)), + Ok(ResponseStreamResult::Err { error, .. }) => { + Some(Err(anyhow!(error.message))) + } + Err(error) => Some(Err(anyhow!(error))), } - Some(result) } } - Err(e) => { - eprintln!("Error reading line: {e}"); - Some(Err(e.into())) - } + Err(error) => Some(Err(anyhow!(error))), } }) .boxed())