add back image fetch failure handling
idiot api gives 200 json
This commit is contained in:
parent
4e078a857a
commit
c7c844f2f0
1 changed files with 38 additions and 13 deletions
|
@ -80,6 +80,11 @@ pub struct Client {
|
||||||
base_url: reqwest::Url,
|
base_url: reqwest::Url,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ByteResponse {
|
||||||
|
bytes: Bytes,
|
||||||
|
content_type: String,
|
||||||
|
}
|
||||||
|
|
||||||
fn random_salt(length: usize) -> String {
|
fn random_salt(length: usize) -> String {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
std::iter::repeat(())
|
std::iter::repeat(())
|
||||||
|
@ -155,7 +160,10 @@ impl Client {
|
||||||
Ok(Client { client, base_url })
|
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?
|
// FIXME: is an entire channel per request overkill? maybe pool them?
|
||||||
let (sender, receiver) = async_channel::bounded(1);
|
let (sender, receiver) = async_channel::bounded(1);
|
||||||
|
|
||||||
|
@ -168,12 +176,15 @@ impl Client {
|
||||||
// wrap this logic in a fn so we can use ?
|
// wrap this logic in a fn so we can use ?
|
||||||
async fn perform(
|
async fn perform(
|
||||||
response: Result<reqwest::Response, reqwest_middleware::Error>,
|
response: Result<reqwest::Response, reqwest_middleware::Error>,
|
||||||
) -> Result<Bytes, Error> {
|
) -> Result<ByteResponse, Error> {
|
||||||
let response = response?.error_for_status()?;
|
let response = response?.error_for_status()?;
|
||||||
let xcache = response.headers()[http_cache::XCACHE].to_str().ok();
|
let xcache = response.headers()[http_cache::XCACHE].to_str().ok();
|
||||||
let content_type = response.headers()[reqwest::header::CONTENT_TYPE]
|
let content_type = String::from_utf8(
|
||||||
.to_str()
|
response.headers()[reqwest::header::CONTENT_TYPE]
|
||||||
.ok();
|
.as_bytes()
|
||||||
|
.to_vec(),
|
||||||
|
)
|
||||||
|
.expect("invalid content type (required)");
|
||||||
event!(
|
event!(
|
||||||
name: "response",
|
name: "response",
|
||||||
target: "audrey::http",
|
target: "audrey::http",
|
||||||
|
@ -181,12 +192,16 @@ impl Client {
|
||||||
url=response.url().as_str(),
|
url=response.url().as_str(),
|
||||||
status=response.status().as_str(),
|
status=response.status().as_str(),
|
||||||
cache_status=xcache,
|
cache_status=xcache,
|
||||||
content_type=content_type
|
content_type=&content_type
|
||||||
);
|
);
|
||||||
response
|
let bytes = response
|
||||||
.bytes()
|
.bytes()
|
||||||
.await
|
.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
|
sender
|
||||||
|
@ -211,7 +226,7 @@ impl Client {
|
||||||
url
|
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
|
self.send(self.client.get(url)).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,8 +234,8 @@ impl Client {
|
||||||
&self,
|
&self,
|
||||||
url: url::Url,
|
url: url::Url,
|
||||||
) -> Result<T, Error> {
|
) -> Result<T, Error> {
|
||||||
let bytes = self.get_bytes(url).await?;
|
let byteresponse = self.get_bytes(url).await?;
|
||||||
serde_json::from_slice::<T>(&bytes).map_err(Error::JsonDecodeError)
|
serde_json::from_slice::<T>(&byteresponse.bytes).map_err(Error::JsonDecodeError)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_subsonic<T: serde::de::DeserializeOwned + Send + 'static>(
|
async fn get_subsonic<T: serde::de::DeserializeOwned + Send + 'static>(
|
||||||
|
@ -266,9 +281,19 @@ impl Client {
|
||||||
size: Option<u32>,
|
size: Option<u32>,
|
||||||
) -> Result<gtk::gdk_pixbuf::Pixbuf, Error> {
|
) -> Result<gtk::gdk_pixbuf::Pixbuf, Error> {
|
||||||
let url = self.cover_art_url(id, size);
|
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(
|
let image = ImageReader::new(std::io::BufReader::new(std::io::Cursor::new(
|
||||||
cover_art_bytes,
|
byteresponse.bytes,
|
||||||
)))
|
)))
|
||||||
.with_guessed_format()
|
.with_guessed_format()
|
||||||
.map_err(|e| Error::ImageDecodeError(image::ImageError::IoError(e)))?
|
.map_err(|e| Error::ImageDecodeError(image::ImageError::IoError(e)))?
|
||||||
|
|
Loading…
Reference in a new issue