Skip to content

Commit 64df967

Browse files
fix: show request id on errors encountered during the response stream (#842)
1 parent 4b4277c commit 64df967

File tree

3 files changed

+61
-13
lines changed

3 files changed

+61
-13
lines changed

crates/fig_api_client/src/clients/streaming_client.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,14 @@ pub enum SendMessageOutput {
178178
}
179179

180180
impl SendMessageOutput {
181+
pub fn request_id(&self) -> Option<&str> {
182+
match self {
183+
SendMessageOutput::Codewhisperer(output) => output.request_id(),
184+
SendMessageOutput::QDeveloper(output) => output.request_id(),
185+
SendMessageOutput::Mock(_) => None,
186+
}
187+
}
188+
181189
pub async fn recv(&mut self) -> Result<Option<ChatResponseStream>, Error> {
182190
match self {
183191
SendMessageOutput::Codewhisperer(output) => Ok(output

crates/q_cli/src/cli/chat/mod.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ use fig_util::CLI_BINARY_NAME;
5151
use input_source::InputSource;
5252
use parser::{
5353
RecvError,
54+
RecvErrorKind,
5455
ResponseParser,
5556
ToolUse,
5657
};
@@ -1065,8 +1066,12 @@ where
10651066
},
10661067
}
10671068
},
1068-
Err(RecvError::StreamTimeout { source, duration }) => {
1069+
Err(RecvError {
1070+
request_id,
1071+
source: RecvErrorKind::StreamTimeout { source, duration },
1072+
}) => {
10691073
error!(
1074+
request_id,
10701075
?source,
10711076
"Encountered a stream timeout after waiting for {}s",
10721077
duration.as_secs()
@@ -1095,14 +1100,18 @@ where
10951100
.await?,
10961101
));
10971102
},
1098-
Err(RecvError::UnexpectedToolUseEos {
1099-
tool_use_id,
1100-
name,
1101-
message,
1103+
Err(RecvError {
1104+
request_id,
1105+
source:
1106+
RecvErrorKind::UnexpectedToolUseEos {
1107+
tool_use_id,
1108+
name,
1109+
message,
1110+
},
11021111
}) => {
11031112
error!(
1104-
tool_use_id,
1105-
name, "The response stream ended before the entire tool use was received"
1113+
request_id,
1114+
tool_use_id, name, "The response stream ended before the entire tool use was received"
11061115
);
11071116
if self.interactive {
11081117
execute!(self.output, cursor::Hide)?;

crates/q_cli/src/cli/chat/parser.rs

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,26 @@ impl From<ToolUse> for FigToolUse {
4141
}
4242

4343
#[derive(Debug, Error)]
44-
pub enum RecvError {
44+
pub struct RecvError {
45+
/// The request id associated with the [SendMessageOutput] stream.
46+
pub request_id: Option<String>,
47+
#[source]
48+
pub source: RecvErrorKind,
49+
}
50+
51+
impl std::fmt::Display for RecvError {
52+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53+
write!(f, "Failed to receive the next message: ")?;
54+
if let Some(request_id) = self.request_id.as_ref() {
55+
write!(f, "request_id: {}, error: ", request_id)?;
56+
}
57+
write!(f, "{}", self.source)?;
58+
Ok(())
59+
}
60+
}
61+
62+
#[derive(Debug, Error)]
63+
pub enum RecvErrorKind {
4564
#[error("{0}")]
4665
Client(#[from] fig_api_client::Error),
4766
#[error("{0}")]
@@ -223,13 +242,13 @@ impl ResponseParser {
223242
content: std::mem::take(&mut self.assistant_text),
224243
tool_uses: Some(self.tool_uses.clone().into_iter().map(Into::into).collect()),
225244
});
226-
return Err(RecvError::UnexpectedToolUseEos {
245+
return Err(self.error(RecvErrorKind::UnexpectedToolUseEos {
227246
tool_use_id: id,
228247
name,
229248
message,
230-
});
249+
}));
231250
} else {
232-
return Err(err.into());
251+
return Err(self.error(err));
233252
}
234253
},
235254
};
@@ -266,13 +285,25 @@ impl ResponseParser {
266285
},
267286
Err(err) => {
268287
if duration.as_secs() >= 59 {
269-
Err(RecvError::StreamTimeout { source: err, duration })
288+
Err(self.error(RecvErrorKind::StreamTimeout { source: err, duration }))
270289
} else {
271-
Err(err.into())
290+
Err(self.error(err))
272291
}
273292
},
274293
}
275294
}
295+
296+
fn request_id(&self) -> Option<&str> {
297+
self.response.request_id()
298+
}
299+
300+
/// Helper to create a new [RecvError] populated with the associated request id for the stream.
301+
fn error(&self, source: impl Into<RecvErrorKind>) -> RecvError {
302+
RecvError {
303+
request_id: self.request_id().map(str::to_string),
304+
source: source.into(),
305+
}
306+
}
276307
}
277308

278309
#[derive(Debug)]

0 commit comments

Comments
 (0)