diff --git a/backend/src/utils/routing.rs b/backend/src/utils/routing.rs index f364bda..e2172cd 100644 --- a/backend/src/utils/routing.rs +++ b/backend/src/utils/routing.rs @@ -1,11 +1,12 @@ use hyper::{Body, Request, Response, StatusCode, header}; +use core::prelude::v1::derive; use std::option::Option::None; use std::result::Result::Ok; +use std::string::ToString; use std::{collections::HashMap}; use std::convert::{From, Infallible}; use std::sync::Arc; use chrono::{DateTime, Local}; -use rand; use rand::seq::IteratorRandom; use serde::Serialize; @@ -25,6 +26,11 @@ struct ProblemResponse { difficulty: Option, } +#[derive(Serialize)] +struct ErrorResponse { + message: String, +} + async fn get_parameter(req: &Request) -> HashMap { let query = req.uri().query().unwrap_or(""); url::form_urlencoded::parse(query.as_bytes()) @@ -99,8 +105,14 @@ pub async fn router(req: Request, state: Arc) -> Result { - let mut not_found = Response::new(Body::from("No problem found in given range.")); + let error_body = serde_json::to_string(&ErrorResponse { + message: "指定Diff範囲に該当する問題がありませんでした".to_string(), + }).unwrap(); + + let mut not_found = Response::new(Body::from(error_body)); *not_found.status_mut() = StatusCode::NOT_FOUND; + not_found.headers_mut().insert(header::CONTENT_TYPE, "application/json".parse().unwrap()); + Ok(with_cors_headers(not_found)) } } diff --git a/backend/tests/routing_test.rs b/backend/tests/routing_test.rs index 71b66df..c9249e3 100644 --- a/backend/tests/routing_test.rs +++ b/backend/tests/routing_test.rs @@ -14,13 +14,11 @@ fn build_test_state() -> Arc { ProblemModel { difficulty: Some(1000.0) }, ); - let problems = vec![ - Problem { - id: "abc001_a".to_string(), - contest_id: "abc001".to_string(), - name: "A - Test Problem".to_string(), - } - ]; + let problems = vec![Problem { + id: "abc001_a".to_string(), + contest_id: "abc001".to_string(), + name: "A - Test Problem".to_string(), + }]; Arc::new(AppState { problems, @@ -56,7 +54,14 @@ async fn test_not_found_path() { async fn test_not_found_problem() { let (status, body) = build_and_send(Method::GET, "/?under=0&over=500").await; assert_eq!(status, StatusCode::NOT_FOUND); - assert_eq!(body, "No problem found in given range."); + + #[derive(serde::Deserialize)] + struct ErrorResponse { + message: String, + } + + let err: ErrorResponse = serde_json::from_str(&body).unwrap(); + assert_eq!(err.message, "指定Diff範囲に該当する問題がありませんでした"); } #[tokio::test] @@ -70,7 +75,7 @@ async fn test_under_greater_than_over() { async fn test_random_range() { let (status, body) = build_and_send(Method::GET, "/?under=500&over=1500").await; assert_eq!(status, StatusCode::OK); - + #[derive(serde::Deserialize)] struct ProblemResponse { id: String, diff --git a/frontend/src/App.svelte b/frontend/src/App.svelte index a8abe8c..9f4289b 100644 --- a/frontend/src/App.svelte +++ b/frontend/src/App.svelte @@ -34,20 +34,28 @@ `${API_URL}/?under=${under_diff}&over=${over_diff}` ); + if (res.status === 404) { + const data = await res.json(); + throw new Error(data.message ?? "指定範囲内に該当する問題がありませんでした"); + } + if (!res.ok) { throw new Error(`HTTPエラー: ${res.status}`); } const json: Problem = await res.json(); - result = json; + + setTimeout(() => { + result = json; + loading = false; + }, 1050); } catch (err) { - errorMessage = (err as Error).message; - result = null; + setTimeout(() => { + errorMessage = (err as Error).message; + result = null; + loading = false; + }, 1050); } - - setTimeout(() => { - loading = false; - }, 2200); } @@ -63,20 +71,17 @@

最低Diffが負の値になっています

{/if} - {#if errorMessage} -

{errorMessage}

- {/if} -
-
@@ -108,6 +113,20 @@ + {:else if errorMessage} +
+ +
+ + +

+ {errorMessage} +

+
+
+
{/if} \ No newline at end of file diff --git a/frontend/src/style.css b/frontend/src/style.css index 9aa544c..369fafe 100644 --- a/frontend/src/style.css +++ b/frontend/src/style.css @@ -1,3 +1,4 @@ +@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@100..900&family=Ubuntu+Sans+Mono:ital,wght@0,400..700;1,400..700&display=swap'); @import "tailwindcss"; @theme {