summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCara Salter <cara@devcara.com>2022-05-30 00:01:39 -0400
committerCara Salter <cara@devcara.com>2022-05-30 00:01:39 -0400
commit3ec1485ae7856e76db8eb2f305ef5950e60f7d8c (patch)
tree09885a51cfc3fe9d2ba45356df2347ec59ee2c22
parent7ba652e291bb52d97faa6d21e7821a64664a00ae (diff)
downloadhomeworld-3ec1485ae7856e76db8eb2f305ef5950e60f7d8c.tar.gz
homeworld-3ec1485ae7856e76db8eb2f305ef5950e60f7d8c.zip
errors/handlers: Make 404 errors more clear
Instead of returning a 500 for every error, this should make it a little easier to return specific status codes for different errors
-rw-r--r--src/errors.rs10
-rw-r--r--src/handlers/ships.rs19
2 files changed, 25 insertions, 4 deletions
diff --git a/src/errors.rs b/src/errors.rs
index 42477c0..c1d6672 100644
--- a/src/errors.rs
+++ b/src/errors.rs
@@ -12,6 +12,9 @@ pub enum ServiceError {
#[error("SQL error: {0}")]
Sql(#[from] sqlx::Error),
+
+ #[error("Not Found")]
+ NotFound,
}
pub type StringResult<T = &'static str> = Result<T, ServiceError>;
@@ -22,8 +25,13 @@ impl IntoResponse for ServiceError {
fn into_response(self) -> Response {
let body = body::boxed(body::Full::from(self.to_string()));
+ let status = match self {
+ ServiceError::NotFound => StatusCode::NOT_FOUND,
+ _ => StatusCode::INTERNAL_SERVER_ERROR,
+ };
+
Response::builder()
- .status(StatusCode::INTERNAL_SERVER_ERROR)
+ .status(status)
.body(body)
.unwrap()
}
diff --git a/src/handlers/ships.rs b/src/handlers/ships.rs
index ddb81a6..75f5dc5 100644
--- a/src/handlers/ships.rs
+++ b/src/handlers/ships.rs
@@ -1,10 +1,11 @@
use std::sync::Arc;
use axum::{Json, extract::Path, Extension};
+use hyper::StatusCode;
use solarlib::ship::{Ship, DbShip, Sha256};
-use sqlx::{query_as, query};
+use sqlx::{query_as, query, Error as SqlxError};
-use crate::{errors::{JsonResult, StringResult}, State};
+use crate::{errors::{JsonResult, StringResult, ServiceError}, State};
pub async fn list(state: Extension<Arc<State>>) -> JsonResult<Json<Vec<Ship>>> {
@@ -38,7 +39,19 @@ pub async fn delete(Path(shasum): Path<Sha256>, state: Extension<Arc<State>>) ->
pub async fn get(Path(shasum): Path<Sha256>, state: Extension<Arc<State>>) -> JsonResult<Json<DbShip>> {
let mut conn = state.conn.acquire().await?;
- let db_ship = query_as!(DbShip, "SELECT * FROM ships WHERE shasum=$1", shasum.to_string()).fetch_one(&mut conn).await?;
+ let db_ship = match query_as!(DbShip, "SELECT * FROM ships WHERE shasum=$1", shasum.to_string()).fetch_one(&mut conn).await {
+ Ok(d) => d,
+ Err(e) => {
+ match e {
+ SqlxError::RowNotFound => {
+ return Err(ServiceError::NotFound)
+ },
+ _ => {
+ return Err(e.into());
+ }
+ }
+ },
+ };
Ok(Json(db_ship))
}