From 83932cc297381b8ef0f8f9afbeb3b3f682288de6 Mon Sep 17 00:00:00 2001 From: Austen Adler Date: Sat, 25 Feb 2023 18:54:44 -0500 Subject: [PATCH] Properly send errors in api --- Cargo.toml | 2 ++ web/src/main.rs | 45 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0c46b1f..8ed35c3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,8 @@ members = [ ] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[features] +default = [] [dependencies] s2 = {version="0.0.12", default-features=false} diff --git a/web/src/main.rs b/web/src/main.rs index be4ff66..a1634fd 100644 --- a/web/src/main.rs +++ b/web/src/main.rs @@ -1,6 +1,6 @@ use std::str::FromStr; -use rocket::{get, routes, serde::json::Json}; +use rocket::{get, routes, serde::json::Json, Responder}; use serde::{Deserialize, Serialize}; use this_algorithm::Address; @@ -18,20 +18,30 @@ async fn main() -> Result<(), Box> { } #[get("/address?&")] -async fn get_address(lat: f64, lon: f64) -> Result { - Address::from_lat_lon(lat, lon) - .map(|a| a.to_string()) - .map_err(|e| e.to_string()) +async fn get_address(lat: Option, lon: Option) -> Result { + let (lat, lon) = lat.zip(lon).ok_or(ApiError::InvalidRequest( + "lat and lon parameters are required", + ))?; + let lat = lat + .parse::() + .map_err(|_| ApiError::InvalidRequest("Invalid lat parameter"))?; + let lon = lon + .parse::() + .map_err(|_| ApiError::InvalidRequest("Invalid lon parameter"))?; + + Ok(Address::from_lat_lon(lat, lon)?.to_string()) } #[get("/coords?
")] -async fn get_coords(address: String) -> Result, String> { +async fn get_coords(address: Option) -> Result, ApiError> { + let address = address.ok_or(ApiError::InvalidRequest("address parameter required"))?; + Address::from_str(&address) .as_ref() + .map_err(Into::into) .map(Address::to_lat_lon) .map(Coords::from) .map(Json) - .map_err(|e| e.to_string()) } #[derive(Serialize, Deserialize)] @@ -45,3 +55,24 @@ impl From<(f64, f64)> for Coords { Self { lat, lon } } } + +#[derive(Responder)] +#[response(status = 400)] +enum ApiError { + #[response(status = 400)] + AlgorithmError(String), + #[response(status = 400)] + InvalidRequest(&'static str), +} + +impl From<&this_algorithm::Error> for ApiError { + fn from(e: &this_algorithm::Error) -> Self { + Self::AlgorithmError(e.to_string()) + } +} + +impl From for ApiError { + fn from(e: this_algorithm::Error) -> Self { + Self::from(&e) + } +}