sigoden/aichat · error
(type: )
Error message
{message} (type: {typ}) What it means
The upstream API returned a non-2xx response whose JSON body contains an error object with 'type' and 'message' fields (the OpenAI/Gemini-style error envelope). The message is the provider's own description (e.g. 'rate limit exceeded', 'invalid api key') and the type is the provider's error classification. This branch fires only when the response parsed as JSON with an error object.
Solutions
- Check the error type against known provider classes (rate_limit_error, authentication_error, invalid_request_error) and branch accordingly
- Retry with exponential backoff and jitter for rate-limit or transient server error types
- For authentication errors, prompt the user to re-validate credentials instead of retrying
- Log the full response body at debug level to preserve diagnostics the message alone lacks
Defensive patterns
Strategy: retry
When it happens
Trigger: Thrown at src/client/common.rs:503 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of sigoden/aichat@82976d349a (2026-09-09).
Data as JSON: /api/errors/ebd5fa788038af1f.
Report an issue: GitHub.
Appendix: source
Thrown at src/client/common.rs:503
pub fn noop_prepare_rerank<T>(_client: &T, _data: &RerankData) -> Result<RequestData> {
bail!("The client doesn't support rerank api")
}
pub async fn noop_rerank(_builder: RequestBuilder, _model: &Model) -> Result<RerankOutput> {
bail!("The client doesn't support rerank api")
}
pub fn catch_error(data: &Value, status: u16) -> Result<()> {
if (200..300).contains(&status) {
return Ok(());
}
debug!("Invalid response, status: {status}, data: {data}");
if let Some(error) = data["error"].as_object() {
if let (Some(typ), Some(message)) = (
json_str_from_map(error, "type"),
json_str_from_map(error, "message"),
) {
bail!("{message} (type: {typ})");
} else if let (Some(typ), Some(message)) = (
json_str_from_map(error, "code"),
json_str_from_map(error, "message"),
) {
bail!("{message} (code: {typ})");
}
} else if let Some(error) = data["errors"][0].as_object() {
if let (Some(code), Some(message)) = (
error.get("code").and_then(|v| v.as_u64()),
json_str_from_map(error, "message"),
) {
bail!("{message} (status: {code})")
}
} else if let Some(error) = data[0]["error"].as_object() {
if let (Some(status), Some(message)) = (
json_str_from_map(error, "status"),
json_str_from_map(error, "message"),
) {View on GitHub (pinned to 82976d349a)