From 2e86f69e65a135ad9dc43a700ac4638e41bcde04 Mon Sep 17 00:00:00 2001 From: Baitinq Date: Mon, 31 Oct 2022 00:00:40 +0100 Subject: Frontend: Handle and show API errors --- frontend/src/app.rs | 103 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 71 insertions(+), 32 deletions(-) diff --git a/frontend/src/app.rs b/frontend/src/app.rs index 024ea6c..20e081c 100644 --- a/frontend/src/app.rs +++ b/frontend/src/app.rs @@ -25,7 +25,7 @@ fn result_component(props: &ResultComponentProps) -> Html { pub struct OSSE { pub search_query: String, - pub results: Option>, //TODO: some loading? + pub results: Option, String>>, //TODO: some loading? } #[derive(Properties, PartialEq, Eq)] @@ -38,7 +38,7 @@ pub struct OSSEProps { pub enum OSSEMessage { SearchSubmitted, SearchChanged(String), - SearchFinished(Vec), + SearchFinished(Result, String>), } impl Component for OSSE { @@ -57,17 +57,29 @@ impl Component for OSSE { ctx.link().send_future(async move { let endpoint = format!("{}/search/{}", api_endpoint, initial_search_query); - let fetched_response = Request::get(endpoint.as_str()).send().await.unwrap(); + let fetched_response = match Request::get(endpoint.as_str()).send().await { + Ok(response) => response, + Err(_) => { + return OSSEMessage::SearchFinished(Err( + "Failed to connect to the API!".to_string() + )) + } + }; let fetched_results: Vec = match fetched_response.json().await { - Err(e) => panic!("Im panic: {}", e), + Err(_) => { + return OSSEMessage::SearchFinished(Err( + "Internal API Error!".to_string() + )) + } Ok(json) => json, }; - OSSEMessage::SearchFinished(fetched_results) + OSSEMessage::SearchFinished(Ok(fetched_results)) }); } + //WE may have data race between the future and the actual creation. OSSE { search_query: urlencoding::decode(search_query.as_str()) .to_owned() @@ -91,15 +103,26 @@ impl Component for OSSE { ctx.link().send_future(async move { let endpoint = format!("{}/search/{}", api_endpoint, search_query); - let fetched_response = Request::get(endpoint.as_str()).send().await.unwrap(); + let fetched_response = match Request::get(endpoint.as_str()).send().await { + Ok(response) => response, + Err(_) => { + return OSSEMessage::SearchFinished(Err( + "Failed to connect to the API!".to_string(), + )) + } + }; let fetched_results: Vec = match fetched_response.json().await { - Err(e) => panic!("Im panic: {}", e), + Err(_) => { + return OSSEMessage::SearchFinished(Err( + "Internal API Error!".to_string() + )) + } Ok(json) => json, }; - OSSEMessage::SearchFinished(fetched_results) + OSSEMessage::SearchFinished(Ok(fetched_results)) }); false @@ -110,7 +133,14 @@ impl Component for OSSE { true } OSSEMessage::SearchFinished(search_results) => { - self.results = Some(search_results); + match search_results { + Ok(results) => { + self.results = Some(Ok(results)); + } + Err(error) => { + self.results = Some(Err(error)); + } + }; true } @@ -133,31 +163,40 @@ impl Component for OSSE { OSSEMessage::SearchChanged(input) }); - let display_results = |maybe_results: &Option>| -> Html { - let maybe_results = maybe_results.as_ref(); - if maybe_results.is_none() { - return html! {}; - } + let display_results = + |maybe_results: &Option, String>>| -> Html { + if maybe_results.is_none() { + return html! {}; + } - let results = maybe_results.unwrap(); - if !results.is_empty() { - results - .iter() - .sorted() - .map(|r| { - html! { -
- -
- } - }) - .collect::() - } else { - html! { -

{"No results!"}

+ let results = maybe_results.as_ref().unwrap(); + + if results.is_err() { + return html! { +

{format!("ERROR: {}", results.as_ref().err().unwrap())}

+ }; } - } - }; + + let results = results.as_ref().unwrap(); + + if !results.is_empty() { + results + .iter() + .sorted() + .map(|r| { + html! { +
+ +
+ } + }) + .collect::() + } else { + html! { +

{"No results!"}

+ } + } + }; html! { <> -- cgit 1.4.1