66 lines
2.0 KiB
Markdown
66 lines
2.0 KiB
Markdown
---
|
|
id: 27a1f728-ec90-469c-a6ab-5644d333322f
|
|
type: fix
|
|
title: "Rust: reqwest response.json() yields reqwest::Error, not serde_json::Error"
|
|
tags: [rust, reqwest, serde, error-handling, serde_json, api]
|
|
importance: 0.5
|
|
confidence: 0.8
|
|
created: "2026-02-28T04:58:15.771467+00:00"
|
|
updated: "2026-02-28T16:53:52.215098+00:00"
|
|
relations:
|
|
- target: 4dc83eed-b0b1-4924-b82e-faf352426785
|
|
type: RELATED_TO
|
|
direction: incoming
|
|
strength: 0.9
|
|
edge_id: f57f63b8-1a05-4645-a320-4b045569ff55
|
|
- target: 3ecd877b-de73-4afd-b328-b3ee99f5a1e3
|
|
type: CAUSES
|
|
direction: incoming
|
|
strength: 0.9
|
|
edge_id: 08588ede-b8fa-4b19-9c7e-b513808fa2e7
|
|
- target: 0e484de1-cb92-479c-95ec-06fa9e886c0c
|
|
type: RELATED_TO
|
|
direction: incoming
|
|
strength: 0.7
|
|
edge_id: 67fc682d-2b46-43c8-b950-bd80147e0056
|
|
- target: 23121a41-790a-4bf3-9a4b-39f299bc4015
|
|
type: RELATED_TO
|
|
direction: incoming
|
|
strength: 0.8
|
|
edge_id: 28a2471d-a080-4344-ab1e-5413df9e072c
|
|
---
|
|
|
|
# Fix: reqwest JSON Error Type Mismatch
|
|
|
|
## Problem
|
|
|
|
When using `response.json::<T>().await`, JSON decode failures produce a `reqwest::Error` — not a `serde_json::Error`. This means a custom error variant like:
|
|
|
|
```rust
|
|
#[derive(Debug, thiserror::Error)]
|
|
enum ApiError {
|
|
#[error("Parse error: {0}")]
|
|
Parse(#[from] serde_json::Error),
|
|
// ...
|
|
}
|
|
```
|
|
|
|
...is **unreachable** if you only call `response.json()`. The `#[from]` impl exists but can never fire.
|
|
|
|
## Fix
|
|
|
|
Decode manually in two steps so the `serde_json::Error` is produced directly:
|
|
|
|
```rust
|
|
let body = response.text().await.map_err(ApiError::Request)?;
|
|
let data = serde_json::from_str::<T>(&body).map_err(ApiError::Parse)?;
|
|
```
|
|
|
|
## Why It Matters
|
|
|
|
This lets callers distinguish **network errors** (connection dropped, timeout) from **JSON parse errors** (malformed response, schema mismatch). With `response.json()`, both collapse into `reqwest::Error` and you lose that distinction.
|
|
|
|
## Context
|
|
|
|
Caught during code review of `api/client.rs` in SBA Scout Rust rewrite Phase 2.
|