mirror of
https://github.com/infinilabs/coco-app.git
synced 2025-12-16 19:47:43 +01:00
fix: several issues around search (#502)
* fix: several issues around search * chore: update release notes
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -24,7 +24,9 @@ pub async fn get_response_body_text(response: Response) -> Result<String, String
|
||||
let body = response
|
||||
.text()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to read response body: {}", e))?;
|
||||
.map_err(|e| format!("Failed to read response body: {}, code: {}", e, status))?;
|
||||
|
||||
log::debug!("Response status: {}, body: {}", status, &body);
|
||||
|
||||
if status < 200 || status >= 400 {
|
||||
// Try to parse the error body
|
||||
|
||||
@@ -82,6 +82,18 @@ pub async fn query_coco_fusion<R: Runtime>(
|
||||
.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<R: Runtime>(
|
||||
});
|
||||
}
|
||||
// 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<R: Runtime>(
|
||||
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,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -34,6 +34,10 @@ pub async fn refresh_all_connectors<R: Runtime>(app_handle: &AppHandle<R>) -> 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
|
||||
{
|
||||
|
||||
@@ -47,6 +47,10 @@ pub async fn refresh_all_datasources<R: Runtime>(_app_handle: &AppHandle<R>) ->
|
||||
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) => {
|
||||
|
||||
@@ -12,7 +12,7 @@ pub static HTTP_CLIENT: Lazy<Mutex<Client>> = 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<HashMap<String, String>>,
|
||||
body: Option<reqwest::Body>,
|
||||
) -> Result<reqwest::Response, String> {
|
||||
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 {
|
||||
|
||||
@@ -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<RequestBuilder, String> {
|
||||
self.build_request(query.from, query.size, &query.query_strings)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn build_request(
|
||||
&self,
|
||||
from: u64,
|
||||
size: u64,
|
||||
query_strings: &HashMap<String, String>,
|
||||
) -> Result<RequestBuilder, String> {
|
||||
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<QueryResponse, SearchError> {
|
||||
// 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<String, JsonValue> = 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)
|
||||
|
||||
@@ -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::<SearchSourceRegistry>();
|
||||
let source = CocoSearchSource::new(server.clone(), Client::new());
|
||||
let source = CocoSearchSource::new(server.clone());
|
||||
registry.register_source(source).await;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,9 @@ async function invokeWithErrorHandler<T>(
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user