add back image fetch failure handling

idiot api gives 200 json
This commit is contained in:
psykose 2024-11-19 13:57:25 +01:00
parent 4e078a857a
commit c7c844f2f0
Signed by: psykose
SSH key fingerprint: SHA256:pRMVjV3kRB6zl+wNx+sV8KoMnPqQAW6v8dNCxsCGZv8

View file

@ -80,6 +80,11 @@ pub struct Client {
base_url: reqwest::Url,
}
struct ByteResponse {
bytes: Bytes,
content_type: String,
}
fn random_salt(length: usize) -> String {
let mut rng = rand::thread_rng();
std::iter::repeat(())
@ -155,7 +160,10 @@ impl Client {
Ok(Client { client, base_url })
}
async fn send(&self, request: reqwest_middleware::RequestBuilder) -> Result<Bytes, Error> {
async fn send(
&self,
request: reqwest_middleware::RequestBuilder,
) -> Result<ByteResponse, Error> {
// FIXME: is an entire channel per request overkill? maybe pool them?
let (sender, receiver) = async_channel::bounded(1);
@ -168,12 +176,15 @@ impl Client {
// wrap this logic in a fn so we can use ?
async fn perform(
response: Result<reqwest::Response, reqwest_middleware::Error>,
) -> Result<Bytes, Error> {
) -> Result<ByteResponse, Error> {
let response = response?.error_for_status()?;
let xcache = response.headers()[http_cache::XCACHE].to_str().ok();
let content_type = response.headers()[reqwest::header::CONTENT_TYPE]
.to_str()
.ok();
let content_type = String::from_utf8(
response.headers()[reqwest::header::CONTENT_TYPE]
.as_bytes()
.to_vec(),
)
.expect("invalid content type (required)");
event!(
name: "response",
target: "audrey::http",
@ -181,12 +192,16 @@ impl Client {
url=response.url().as_str(),
status=response.status().as_str(),
cache_status=xcache,
content_type=content_type
content_type=&content_type
);
response
let bytes = response
.bytes()
.await
.map_err(|e| Error::ReqwestError(reqwest_middleware::Error::Reqwest(e)))
.map_err(|e| Error::ReqwestError(reqwest_middleware::Error::Reqwest(e)))?;
Ok(ByteResponse {
bytes,
content_type,
})
}
sender
@ -211,7 +226,7 @@ impl Client {
url
}
async fn get_bytes(&self, url: url::Url) -> Result<Bytes, Error> {
async fn get_bytes(&self, url: url::Url) -> Result<ByteResponse, Error> {
self.send(self.client.get(url)).await
}
@ -219,8 +234,8 @@ impl Client {
&self,
url: url::Url,
) -> Result<T, Error> {
let bytes = self.get_bytes(url).await?;
serde_json::from_slice::<T>(&bytes).map_err(Error::JsonDecodeError)
let byteresponse = self.get_bytes(url).await?;
serde_json::from_slice::<T>(&byteresponse.bytes).map_err(Error::JsonDecodeError)
}
async fn get_subsonic<T: serde::de::DeserializeOwned + Send + 'static>(
@ -266,9 +281,19 @@ impl Client {
size: Option<u32>,
) -> Result<gtk::gdk_pixbuf::Pixbuf, Error> {
let url = self.cover_art_url(id, size);
let cover_art_bytes = self.get_bytes(url).await?;
let byteresponse = self.get_bytes(url).await?;
if byteresponse.content_type == "application/json" {
let json =
serde_json::from_slice::<schema::SubsonicResponseOuter<()>>(&byteresponse.bytes)
.map_err(Error::JsonDecodeError)?;
let error = match json.subsonic_response {
schema::SubsonicResponse::Failed { error } => Err(Error::SubsonicError(error)),
_ => panic!("error response didn't get parsed as error"),
};
return error;
}
let image = ImageReader::new(std::io::BufReader::new(std::io::Cursor::new(
cover_art_bytes,
byteresponse.bytes,
)))
.with_guessed_format()
.map_err(|e| Error::ImageDecodeError(image::ImageError::IoError(e)))?