Skip to content

Commit 0885a26

Browse files
Make error message for ApiError more user-friendly (64bit#240)
* Make error message for `APIError` more user-friendly * Make comment clearer * Make comment clearer * Simplify `thiserror` notation
1 parent ecb7468 commit 0885a26

File tree

1 file changed

+26
-1
lines changed

1 file changed

+26
-1
lines changed

async-openai/src/error.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ pub enum OpenAIError {
77
#[error("http error: {0}")]
88
Reqwest(#[from] reqwest::Error),
99
/// OpenAI returns error object with details of API call failure
10-
#[error("{:?}: {}", .0.r#type, .0.message)]
10+
#[error("{0}")]
1111
ApiError(ApiError),
1212
/// Error when a response cannot be deserialized into a Rust type
1313
#[error("failed to deserialize api response: {0}")]
@@ -36,6 +36,31 @@ pub struct ApiError {
3636
pub code: Option<String>,
3737
}
3838

39+
impl std::fmt::Display for ApiError {
40+
/// If all fields are available, `ApiError` is formatted as:
41+
/// `{type}: {message} (param: {param}) (code: {code})`
42+
/// Otherwise, missing fields will be ignored.
43+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44+
let mut parts = Vec::new();
45+
46+
if let Some(r#type) = &self.r#type {
47+
parts.push(format!("{}:", r#type));
48+
}
49+
50+
parts.push(self.message.clone());
51+
52+
if let Some(param) = &self.param {
53+
parts.push(format!("(param: {param})"));
54+
}
55+
56+
if let Some(code) = &self.code {
57+
parts.push(format!("(code: {code})"));
58+
}
59+
60+
write!(f, "{}", parts.join(" "))
61+
}
62+
}
63+
3964
/// Wrapper to deserialize the error object nested in "error" JSON key
4065
#[derive(Debug, Deserialize)]
4166
pub(crate) struct WrappedError {

0 commit comments

Comments
 (0)