I am still learning rust but having a little hard time understanding how to raise an error. I am trying to consume an API but if something goes wrong (example: the api key is wrong so I get a forbidden) how do I handle this? At the moment since a response was received (even if it was forbidden) there is no error (which makes sense) - how do I trigger an error after inspecting the code? I've been trying:
async fn make_api_call(endpoint: &str) -> Result<Response, Error> {
let client = reqwest::Client::new();
dotenv().ok();
let os_request_url = std::env::var("OS_REQUEST_URL").expect("os_request_url must be set.");
let os_api_key = std::env::var("OS_API_KEY").expect("os_api_key must be set.");
let client_response = client
.get(format!("{os_request_url}{endpoint}"))
.header("X-Api-Key", "os_api_key")
.header(ACCEPT, "application/json")
.send()
.await?;
let status_code = client_response.status().as_u16();
Ok(client_response)
}
I have tried to create my own custom error type but that seems verbose and I'm not sure how I raise this error. The goal would be to handle the error based on the status_code:
#[derive(Debug)]
pub struct APIError {
status_code: u16,
details: String,
}
trait StatusCodeTrait: Debug {
fn status_code(&self) -> &u16;
}
impl StatusCodeTrait for APIError {
fn status_code(&self) -> &u16 {
&self.status_code
}
}
impl Error for APIError {
fn description(&self) -> &str {
&self.details
}
}
impl fmt::Display for APIError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "API Error")
}
}
Please read the documentation for the crates you're using. Reqwest's Response
type has a method Response::error_for_status
.
If you haven't already, I also suggest you read "The Book", especially the chapter on error handling. It will give you all you need to know on how to write custom error types and combine them with those from libraries.