···
use anyhow::{Context, Result};
use serde::{Deserialize, Serialize};
4
+
use thiserror::Error;
6
+
#[derive(Debug, Error)]
7
+
pub enum TurbopufferError {
8
+
#[error("query too long: {message}")]
9
+
QueryTooLong { message: String },
10
+
#[error("turbopuffer API error: {0}")]
12
+
#[error("request failed: {0}")]
13
+
RequestFailed(#[from] reqwest::Error),
15
+
Other(#[from] anyhow::Error),
18
+
#[derive(Debug, Deserialize)]
19
+
struct TurbopufferErrorResponse {
#[derive(Debug, Serialize)]
pub struct QueryRequest {
···
.context(format!("failed to parse query response: {}", body))
67
-
pub async fn bm25_query(&self, query_text: &str, top_k: usize) -> Result<QueryResponse> {
87
+
pub async fn bm25_query(&self, query_text: &str, top_k: usize) -> Result<QueryResponse, TurbopufferError> {
"https://api.turbopuffer.com/v1/vectors/{}/query",
···
"include_attributes": ["url", "name", "filename"],
79
-
log::debug!("turbopuffer BM25 query request: {}", serde_json::to_string_pretty(&request)?);
99
+
if let Ok(pretty) = serde_json::to_string_pretty(&request) {
100
+
log::debug!("turbopuffer BM25 query request: {}", pretty);
···
.header("Authorization", format!("Bearer {}", self.api_key))
88
-
.context("failed to send BM25 query request")?;
if !response.status().is_success() {
let status = response.status();
let body = response.text().await.unwrap_or_default();
93
-
anyhow::bail!("turbopuffer BM25 query failed with status {}: {}", status, body);
115
+
// try to parse turbopuffer error response
116
+
if let Ok(error_resp) = serde_json::from_str::<TurbopufferErrorResponse>(&body) {
117
+
// check if it's a query length error
118
+
if error_resp.error.contains("too long") && error_resp.error.contains("max 1024") {
119
+
return Err(TurbopufferError::QueryTooLong {
120
+
message: error_resp.error,
125
+
return Err(TurbopufferError::ApiError(format!(
126
+
"turbopuffer BM25 query failed with status {}: {}",
96
-
let body = response.text().await.context("failed to read response body")?;
131
+
let body = response.text().await
132
+
.map_err(|e| TurbopufferError::Other(anyhow::anyhow!("failed to read response body: {}", e)))?;
log::debug!("turbopuffer BM25 response: {}", body);
let parsed: QueryResponse = serde_json::from_str(&body)
100
-
.context(format!("failed to parse BM25 query response: {}", body))?;
136
+
.map_err(|e| TurbopufferError::Other(anyhow::anyhow!("failed to parse BM25 query response: {}", e)))?;
// DEBUG: log first result to see what BM25 returns
if let Some(first) = parsed.first() {