Add more error handling on response messages

This commit is contained in:
Joey Hines 2025-06-14 12:06:54 -06:00
parent 353eb865db
commit b8fbf2651e
Signed by: joeyahines
GPG Key ID: 38BA6F25C94C9382
3 changed files with 20 additions and 9 deletions

2
Cargo.lock generated
View File

@ -101,7 +101,7 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]] [[package]]
name = "cta-api" name = "cta-api"
version = "0.3.0" version = "0.4.0"
dependencies = [ dependencies = [
"reqwest", "reqwest",
"serde", "serde",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "cta-api" name = "cta-api"
version = "0.3.0" version = "0.4.0"
edition = "2024" edition = "2024"
description = "CTA API Client" description = "CTA API Client"
authors = ["Joey Hines joey@ahines.net"] authors = ["Joey Hines joey@ahines.net"]

View File

@ -2,7 +2,7 @@ use crate::models::eta::{EtaRequest, EtaResp};
use crate::models::follow::{FollowRequest, FollowResp}; use crate::models::follow::{FollowRequest, FollowResp};
use crate::models::route::{RouteRequest, RouteResp}; use crate::models::route::{RouteRequest, RouteResp};
use crate::models::{CTAResponse, Response}; use crate::models::{CTAResponse, Response};
use reqwest::{Client, Url}; use reqwest::{Client, StatusCode, Url};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use thiserror::Error; use thiserror::Error;
@ -18,8 +18,12 @@ pub enum Error {
ReqwestFailure(#[from] reqwest::Error), ReqwestFailure(#[from] reqwest::Error),
#[error("URL parse failure: {0}")] #[error("URL parse failure: {0}")]
UrlParseError(#[from] url::ParseError), UrlParseError(#[from] url::ParseError),
#[error("Got error number '{0}': {1}")] #[error("Got error number '{1}': {0}")]
CtaError(String, String), CtaError(String, String),
#[error("Got a bad HTTP response code: '{0}'")]
HttpError(u16),
#[error("Got a bad response body: '{0}'")]
BadResponse(String),
} }
pub struct CTAClient { pub struct CTAClient {
@ -44,20 +48,27 @@ impl CTAClient {
) -> Result<V, Error> { ) -> Result<V, Error> {
let url = self.url.join(endpoint)?; let url = self.url.join(endpoint)?;
let resp: Response<V> = self let resp = self
.client .client
.get(url) .get(url)
.query(&req) .query(&req)
.query(&[("outputType", "JSON")]) .query(&[("outputType", "JSON")])
.query(&[("key", &self.key)]) .query(&[("key", &self.key)])
.send() .send()
.await?
.json()
.await?; .await?;
if resp.status() == StatusCode::OK {
let resp_str = resp.text().await?;
let resp: Response<V> =
serde_json::from_str(&resp_str).map_err(|_| Error::BadResponse(resp_str))?;
resp.ctatt.check_error()?; resp.ctatt.check_error()?;
Ok(resp.ctatt) Ok(resp.ctatt)
} else {
Err(Error::HttpError(resp.status().as_u16()))
}
} }
pub async fn fetch_route(&mut self, route: &str) -> Result<RouteResp, Error> { pub async fn fetch_route(&mut self, route: &str) -> Result<RouteResp, Error> {