From 575ef14a23c6ad2bc30cd48d1c21a03aff04dc1c Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Mon, 12 Feb 2024 12:16:59 +0100 Subject: [PATCH] Dont allow empty search queries, error handling for search --- src/backend/api/article.rs | 3 +++ src/frontend/components/nav.rs | 8 +++--- src/frontend/pages/search.rs | 48 +++++++++++++++++++++++----------- 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/src/backend/api/article.rs b/src/backend/api/article.rs index 65083e4..4b208a6 100644 --- a/src/backend/api/article.rs +++ b/src/backend/api/article.rs @@ -235,6 +235,9 @@ pub(super) async fn search_article( Query(query): Query, data: Data, ) -> MyResult>> { + if query.query.is_empty() { + return Err(anyhow!("Query is empty").into()); + } let article = DbArticle::search(&query.query, &data.db_connection)?; Ok(Json(article)) } diff --git a/src/frontend/components/nav.rs b/src/frontend/components/nav.rs index 1f79e42..11afcf6 100644 --- a/src/frontend/components/nav.rs +++ b/src/frontend/components/nav.rs @@ -18,8 +18,8 @@ pub fn Nav() -> impl IntoView { GlobalState::api_client() .get_local_instance() .await - .unwrap() - .registration_open + .map(|i| i.registration_open) + .unwrap_or_default() }, ); @@ -43,7 +43,9 @@ pub fn Nav() -> impl IntoView { ev.prevent_default(); let navigate = leptos_router::use_navigate(); let query = search_query.get(); - navigate(&format!("/search?query={query}"), Default::default()); + if !query.is_empty() { + navigate(&format!("/search?query={query}"), Default::default()); + } }> , instance: Option, } +impl SearchResults { + pub fn is_empty(&self) -> bool { + self.articles.is_empty() && self.instance.is_none() + } +} + #[component] pub fn Search() -> impl IntoView { let params = use_query_map(); let query = move || params.get().get("query").cloned().unwrap(); + let (error, set_error) = create_signal(None::); let search_results = create_resource(query, move |query| async move { + set_error.set(None); let mut search_results = SearchResults::default(); let api_client = GlobalState::api_client(); let url = Url::parse(&query); let search_data = SearchArticleData { query }; let search = api_client.search(&search_data); + match search.await { + Ok(mut a) => search_results.articles.append(&mut a), + Err(e) => set_error.set(Some(e.0.to_string())), + } + // If its a valid url, also attempt to resolve as federation object if let Ok(url) = url { - let resolve_article = api_client.resolve_article(url.clone()); - let resolve_instance = api_client.resolve_instance(url); - let (search, resolve_article, resolve_instance) = - join!(search, resolve_article, resolve_instance); - search_results.instance = resolve_instance.ok(); - if let Ok(article) = resolve_article { - search_results.articles.push(article.article); + match api_client.resolve_article(url.clone()).await { + Ok(a) => search_results.articles.push(a.article), + Err(e) => set_error.set(Some(e.0.to_string())), + } + match api_client.resolve_instance(url).await { + Ok(a) => search_results.instance = Some(a), + Err(e) => set_error.set(Some(e.0.to_string())), } - search_results.articles.append(&mut search.unwrap()) - } else { - search_results.articles.append(&mut search.await.unwrap()) } search_results }); @@ -44,11 +53,20 @@ pub fn Search() -> impl IntoView { view! {

"Search results for "{query}

{ - move || search_results.get().map(|search_results| { - let is_empty = search_results.articles.is_empty() && search_results.instance.is_none(); + move || search_results.get().map(move |search_results| { + let is_empty = search_results.is_empty(); view! { No results found

}> + fallback=move || { + let error_view = move || { + error.get().map(|err| { + view! {

{err}

} + }) + }; + view! { + {error_view} +

No results found

+ }}>
    { // render resolved instance