use reqwest::StatusCode;
use crate::model::InvalidValueError;
#[derive(thiserror::Error, Debug)]
pub enum RedfishError {
#[error("Network error talking to BMC at {url}. {source}")]
NetworkError { url: String, source: reqwest::Error },
#[error("HTTP {status_code} at {url}: {response_body}")]
HTTPErrorCode {
url: String,
status_code: StatusCode,
response_body: String,
},
#[error("Could not deserialize response from {url}. Body: {body}. {source}")]
JsonDeserializeError {
url: String,
body: String,
source: serde_json::Error,
},
#[error("Could not serialize request body for {url}. Obj: {object_debug}. {source}")]
JsonSerializeError {
url: String,
object_debug: String,
source: serde_json::Error,
},
#[error("Remote returned empty body")]
NoContent,
#[error("Remote returned empty header")]
NoHeader,
#[error("No such boot option {0}")]
MissingBootOption(String),
#[error("UnnecessaryOperation such as trying to turn on a machine that is already on.")]
UnnecessaryOperation,
#[error("Missing key {key} in JSON at {url}")]
MissingKey { key: String, url: String },
#[error("Key {key} should be {expected_type} at {url}")]
InvalidKeyType {
key: String,
expected_type: String,
url: String,
},
#[error("Field {field} parse error at {url}: {err}")]
InvalidValue {
url: String,
field: String,
err: InvalidValueError,
},
#[error("BMC is locked down, operation cannot be applied. Disable lockdown and retry.")]
Lockdown,
#[error("BMC vendor does not support this operation: {0}")]
NotSupported(String),
#[error("Could not find user with UserName matching '{0}'")]
UserNotFound(String),
#[error("Reqwest error: '{0}'")]
ReqwestError(#[from] reqwest::Error),
#[error("Issue with file: {0}")]
FileError(String),
#[error("Could not identify BMC vendor")]
MissingVendor,
#[error("Password change required")]
PasswordChangeRequired,
#[error("Maximum amount of user accounts reached. Delete one to continue.")]
TooManyUsers,
#[error("Expected type: {expected}, actual: {actual}. Resource type: {resource_type}, resource uri: {resource_uri}")]
TypeMismatch {
expected: String,
actual: String,
resource_type: String,
resource_uri: String,
},
#[error("DPU not found")]
NoDpu,
#[error("Error: {error}")]
GenericError { error: String },
}
impl RedfishError {
pub fn is_unauthorized(&self) -> bool {
matches!(self, RedfishError::HTTPErrorCode {
url: _,
status_code,
response_body: _,
} if *status_code == StatusCode::UNAUTHORIZED
|| *status_code == StatusCode::FORBIDDEN)
}
pub fn not_found(&self) -> bool {
matches!(self, RedfishError::HTTPErrorCode {
url: _,
status_code,
response_body: _,
} if *status_code == StatusCode::NOT_FOUND)
}
}