Detect when API (login) responses are not correct

* Introduce the `Error::Response` variant so services can raise errors
  if the API response are not valid but a relogin will not help
* Indicate that a login failed for status (error) code 1
* Indicate that an API request failed and relogin is necessary for
  status code 1 or 100
* Raise an error on any non-zero status code otherwise with the message
This commit is contained in:
Paul van Tilburg 2023-01-16 19:57:05 +01:00
parent 93e8295c96
commit e268a6ebca
Signed by: paul
GPG Key ID: C6DE073EDA9EEC4D
2 changed files with 30 additions and 8 deletions

View File

@ -35,9 +35,12 @@ pub(crate) enum Error {
/// This usually indicates that the service needs to login again.
#[error("not/no longer authorized")]
NotAuthorized,
/// The services encountered some other API request error.
/// The service encountered some other API request error.
#[error("API request error: {0}")]
Request(#[from] reqwest::Error)
Request(#[from] reqwest::Error),
/// The service encountered an unsupported API response.
#[error("API service error: {0}")]
Response(String),
}
/// Type alias for service results.

View File

@ -13,7 +13,10 @@ use rocket::async_trait;
use serde::{Deserialize, Deserializer, Serialize};
use url::ParseError;
use crate::{services::Result, Status};
use crate::{
services::{Error, Result},
Status,
};
/// The base URL of Hoymiles API gateway.
const BASE_URL: &str = "https://global.hoymiles.com/platform/api/gateway";
@ -300,9 +303,17 @@ impl super::Service for Service {
.await?;
let login_response_data = match login_response.error_for_status() {
Ok(res) => {
let api_response = res.json::<ApiLoginResponse>().await?;
eprintln!("api_response = {:#?}", &api_response);
api_response.data.expect("No API response data found")
let login_response = res.json::<ApiLoginResponse>().await?;
match login_response.status {
0 => login_response.data.expect("No API response data found"),
1 => return Err(Error::NotAuthorized),
_ => {
return Err(Error::Response(format!(
"{} ({})",
login_response.message, login_response.status
)))
}
}
}
Err(err) => return Err(err.into()),
};
@ -330,8 +341,16 @@ impl super::Service for Service {
let api_data = match api_response.error_for_status() {
Ok(res) => {
let api_response = res.json::<ApiDataResponse>().await?;
eprintln!("api_response = {:#?}", &api_response);
api_response.data.expect("No API response data found")
match api_response.status {
0 => api_response.data.expect("No API response data found"),
1 | 100 => return Err(Error::NotAuthorized),
_ => {
return Err(Error::Response(format!(
"{} ({})",
api_response.message, api_response.status
)))
}
}
}
Err(err) => return Err(err.into()),
};