use std::fmt::Debug;
use pdk_core::classy::hl::{HttpClientError, HttpClientResponse};
use serde::Deserialize;
use thiserror::Error;
const TIMEOUT: u32 = 504;
const PRECONDITION_FAILED: u32 = 412;
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum DistributedStorageError {
#[error("Key not found.")]
KeyNotFound,
#[error("Store not found.")]
StoreNotFound,
#[error("Timeout.")]
Timeout,
#[error("Cas Mismatch.")]
CasMismatch,
#[error("Error performing http client call: {0}.")]
HttpClient(#[from] HttpClientError),
#[error("Unexpected error: {0}.")]
Unexpected(String),
}
#[derive(Deserialize, Debug)]
struct PayloadSharedStorageHttpError {
pub message: String,
}
impl From<HttpClientResponse> for DistributedStorageError {
fn from(response: HttpClientResponse) -> Self {
if response.status_code() == PRECONDITION_FAILED {
return DistributedStorageError::CasMismatch;
}
if response.status_code() == TIMEOUT {
return DistributedStorageError::Timeout;
}
if let Ok(error) = serde_json::from_slice::<PayloadSharedStorageHttpError>(response.body())
{
let message = error.message.to_lowercase();
let message = message.trim_end_matches(".");
if message.starts_with("store") && message.ends_with("not found") {
return DistributedStorageError::StoreNotFound;
} else if message.starts_with("object with key") && message.ends_with("not found") {
return DistributedStorageError::KeyNotFound;
} else {
return DistributedStorageError::Unexpected(error.message);
}
}
DistributedStorageError::Unexpected(format!(
"Unexpected Response:\n\tHeaders: {:?}\n\tBody:{}",
response.headers(),
String::from_utf8_lossy(response.body())
))
}
}