diff --git a/docs/content.en/docs/release-notes/_index.md b/docs/content.en/docs/release-notes/_index.md index 5c02f06a..529bed1e 100644 --- a/docs/content.en/docs/release-notes/_index.md +++ b/docs/content.en/docs/release-notes/_index.md @@ -24,6 +24,8 @@ Information about release notes of Coco Server is provided here. - feat: the search input box supports multi-line input #501 ### 🐛 Bug fix +- fix: several issues around search #502 + ### ✈️ Improvements diff --git a/src-tauri/src/common/http.rs b/src-tauri/src/common/http.rs index bbdefc0c..f1250255 100644 --- a/src-tauri/src/common/http.rs +++ b/src-tauri/src/common/http.rs @@ -24,7 +24,9 @@ pub async fn get_response_body_text(response: Response) -> Result= 400 { // Try to parse the error body diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 5dad276d..d56165a0 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -215,7 +215,7 @@ pub fn run() { }) .build(ctx) .expect("error while running tauri application"); - + app.run(|app_handle, event| match event { #[cfg(target_os = "macos")] tauri::RunEvent::Reopen { diff --git a/src-tauri/src/search/mod.rs b/src-tauri/src/search/mod.rs index 366672ca..01b111d9 100644 --- a/src-tauri/src/search/mod.rs +++ b/src-tauri/src/search/mod.rs @@ -52,7 +52,7 @@ pub async fn query_coco_fusion( timeout(timeout_duration, async { query_source_clone.search(query).await }) - .await + .await })); } @@ -82,6 +82,18 @@ pub async fn query_coco_fusion( .push((query_hit, score)); } } + Ok(Ok(Err(err))) => { + failed_requests.push(FailedRequest { + source: QuerySource { + r#type: "N/A".into(), + name: "N/A".into(), + id: "N/A".into(), + }, + status: 0, + error: Some(err.to_string()), + reason: None, + }); + } Ok(Err(err)) => { failed_requests.push(FailedRequest { source: QuerySource { @@ -95,7 +107,7 @@ pub async fn query_coco_fusion( }); } // Timeout reached, skip this request - Ok(_) => { + _ => { failed_requests.push(FailedRequest { source: QuerySource { r#type: "N/A".into(), @@ -103,19 +115,7 @@ pub async fn query_coco_fusion( id: "N/A".into(), }, status: 0, - error: Some("Query source timed out".to_string()), - reason: None, - }); - } - Err(_) => { - failed_requests.push(FailedRequest { - source: QuerySource { - r#type: "N/A".into(), - name: "N/A".into(), - id: "N/A".into(), - }, - status: 0, - error: Some("Task panicked".to_string()), + error: Some(format!("{:?}", &result)), reason: None, }); } diff --git a/src-tauri/src/server/connector.rs b/src-tauri/src/server/connector.rs index 062289e6..8e736d9d 100644 --- a/src-tauri/src/server/connector.rs +++ b/src-tauri/src/server/connector.rs @@ -34,6 +34,10 @@ pub async fn refresh_all_connectors(app_handle: &AppHandle) -> Re // Collect all the tasks for fetching and refreshing connectors let mut server_map = HashMap::new(); for server in servers { + if !server.enabled { + continue; + } + // dbg!("start fetch connectors for server: {}", &server.id); let connectors = match get_connectors_by_server(app_handle.clone(), server.id.clone()).await { diff --git a/src-tauri/src/server/datasource.rs b/src-tauri/src/server/datasource.rs index be3449e1..75598356 100644 --- a/src-tauri/src/server/datasource.rs +++ b/src-tauri/src/server/datasource.rs @@ -32,7 +32,7 @@ pub fn save_datasource_to_cache(server_id: &str, datasources: Vec) { #[allow(dead_code)] pub fn get_datasources_from_cache(server_id: &str) -> Option> { let cache = DATASOURCE_CACHE.read().unwrap(); // Acquire read lock - // dbg!("cache: {:?}", &cache); + // dbg!("cache: {:?}", &cache); let server_cache = cache.get(server_id)?; // Get the server's cache Some(server_cache.clone()) } @@ -47,6 +47,10 @@ pub async fn refresh_all_datasources(_app_handle: &AppHandle) -> for server in servers { // dbg!("fetch datasources for server: {}", &server.id); + if !server.enabled { + continue; + } + // Attempt to get datasources by server, and continue even if it fails let connectors = match datasource_search(server.id.as_str(), None).await { Ok(connectors) => { @@ -130,8 +134,8 @@ pub async fn datasource_search( None, Some(reqwest::Body::from(body.to_string())), ) - .await - .map_err(|e| format!("Error fetching datasource: {}", e))?; + .await + .map_err(|e| format!("Error fetching datasource: {}", e))?; // Parse the search results from the response let datasources: Vec = parse_search_results(resp).await.map_err(|e| { @@ -186,8 +190,8 @@ pub async fn mcp_server_search( None, Some(reqwest::Body::from(body.to_string())), ) - .await - .map_err(|e| format!("Error fetching datasource: {}", e))?; + .await + .map_err(|e| format!("Error fetching datasource: {}", e))?; // Parse the search results from the response let mcp_server: Vec = parse_search_results(resp).await.map_err(|e| { diff --git a/src-tauri/src/server/http_client.rs b/src-tauri/src/server/http_client.rs index c207fb74..4b43ab28 100644 --- a/src-tauri/src/server/http_client.rs +++ b/src-tauri/src/server/http_client.rs @@ -12,7 +12,7 @@ pub static HTTP_CLIENT: Lazy> = Lazy::new(|| { .read_timeout(Duration::from_secs(3)) // Set a timeout of 3 second .connect_timeout(Duration::from_secs(3)) // Set a timeout of 3 second .timeout(Duration::from_secs(10)) // Set a timeout of 10 seconds - .danger_accept_invalid_certs(true) // example for self-signed certificates + .danger_accept_invalid_certs(true) // allow self-signed certificates .build() .expect("Failed to build client"); Mutex::new(client) @@ -35,6 +35,9 @@ impl HttpClient { headers: Option>, body: Option, ) -> Result { + log::debug!("Sending Request: {}, query_params: {:?}, header: {:?}, body: {:?}",&url, &query_params, &headers, &body); + + let request_builder = Self::get_request_builder(method, url, headers, query_params, body).await; @@ -42,6 +45,9 @@ impl HttpClient { dbg!("Failed to send request: {}", &e); format!("Failed to send request: {}", e) })?; + + log::debug!("Request: {}, Response status: {:?}, header: {:?}",&url, &response.status(),&response.headers()); + Ok(response) } @@ -140,9 +146,7 @@ impl HttpClient { headers.insert("X-API-TOKEN".to_string(), t); } - // dbg!(&server_id); - // dbg!(&url); - // dbg!(&headers); + log::debug!("Sending request to server: {}, url: {}, headers: {:?}", &server_id, &url,&headers); Self::send_raw_request(method, &url, query_params, Some(headers), body).await } else { diff --git a/src-tauri/src/server/search.rs b/src-tauri/src/server/search.rs index 58bb03a6..edc88e22 100644 --- a/src-tauri/src/server/search.rs +++ b/src-tauri/src/server/search.rs @@ -5,12 +5,11 @@ use crate::common::search::{QueryHits, QueryResponse, QuerySource, SearchQuery, use crate::common::server::Server; use crate::common::traits::SearchSource; use crate::server::http_client::HttpClient; -use crate::server::servers::get_server_token; use async_trait::async_trait; // use futures::stream::StreamExt; use ordered_float::OrderedFloat; -use reqwest::{Client, Method, RequestBuilder}; use std::collections::HashMap; +use tauri_plugin_store::JsonValue; // use std::hash::Hash; #[allow(dead_code)] @@ -74,45 +73,11 @@ const COCO_SERVERS: &str = "coco-servers"; pub struct CocoSearchSource { server: Server, - client: Client, } impl CocoSearchSource { - pub fn new(server: Server, client: Client) -> Self { - CocoSearchSource { server, client } - } - - async fn build_request_from_query( - &self, - query: &SearchQuery, - ) -> Result { - self.build_request(query.from, query.size, &query.query_strings) - .await - } - - async fn build_request( - &self, - from: u64, - size: u64, - query_strings: &HashMap, - ) -> Result { - let url = HttpClient::join_url(&self.server.endpoint, "/query/_search"); - let mut request_builder = self.client.request(Method::GET, url); - - if !self.server.public { - if let Some(token) = get_server_token(&self.server.id) - .await? - .map(|t| t.access_token) - { - request_builder = request_builder.header("X-API-TOKEN", token); - } - } - - let result = request_builder - .query(&[("from", &from.to_string()), ("size", &size.to_string())]) - .query(query_strings); - - Ok(result) + pub fn new(server: Server) -> Self { + CocoSearchSource { server } } } @@ -127,17 +92,22 @@ impl SearchSource for CocoSearchSource { } async fn search(&self, query: SearchQuery) -> Result { - // Build the request from the provided query - let request_builder = self - .build_request_from_query(&query) - .await - .map_err(|e| SearchError::InternalError(e.to_string()))?; + let url = "/query/_search"; - // Send the HTTP request and handle errors - let response = request_builder - .send() + let mut query_args: HashMap = HashMap::new(); + query_args.insert("from".into(), JsonValue::Number(query.from.into())); + query_args.insert("size".into(), JsonValue::Number(query.size.into())); + for (key, value) in query.query_strings { + query_args.insert(key, JsonValue::String(value)); + } + + let response = HttpClient::get( + &self.server.id, + &url, + Some(query_args), + ) .await - .map_err(|e| SearchError::HttpError(format!("Failed to send search request: {}", e)))?; + .map_err(|e| SearchError::HttpError(format!("Error to send search request: {}", e)))?; // Use the helper function to parse the response body let response_body = get_response_body_text(response) diff --git a/src-tauri/src/server/servers.rs b/src-tauri/src/server/servers.rs index 4f14fcd6..0d7ca70d 100644 --- a/src-tauri/src/server/servers.rs +++ b/src-tauri/src/server/servers.rs @@ -7,7 +7,7 @@ use crate::server::http_client::HttpClient; use crate::server::search::CocoSearchSource; use crate::COCO_TAURI_STORE; use lazy_static::lazy_static; -use reqwest::{Client, Method}; +use reqwest::Method; use serde_json::from_value; use serde_json::Value as JsonValue; use std::collections::HashMap; @@ -447,7 +447,7 @@ pub async fn try_register_server_to_search_source( ) { if server.enabled { let registry = app_handle.state::(); - let source = CocoSearchSource::new(server.clone(), Client::new()); + let source = CocoSearchSource::new(server.clone()); registry.register_source(source).await; } } diff --git a/src/commands/servers.ts b/src/commands/servers.ts index 557623ae..572cd2a8 100644 --- a/src/commands/servers.ts +++ b/src/commands/servers.ts @@ -30,7 +30,9 @@ async function invokeWithErrorHandler( const failedResult = result as any; if (failedResult.failed?.length > 0) { failedResult.failed.forEach((error: any) => { - // addError(error.error, 'error'); + if (result?.hits?.length == 0) { + addError(error.error, 'error'); + } console.error(error.error); }); } diff --git a/src/components/Search/Search.tsx b/src/components/Search/Search.tsx index 73ed6b0e..1a1e8da9 100644 --- a/src/components/Search/Search.tsx +++ b/src/components/Search/Search.tsx @@ -137,7 +137,7 @@ function Search({
{/* Search Results Panel */} {suggests.length > 0 ? ( - sourceData ? ( + sourceData ? ( ) : (