mirror of
				https://github.com/meilisearch/meilisearch.git
				synced 2025-10-31 07:56:28 +00:00 
			
		
		
		
	Make sure template errors are reported to the LLM and front-end without panicking
This commit is contained in:
		| @@ -394,6 +394,7 @@ UnimplementedExternalFunctionCalling           , InvalidRequest       , NOT_IMPL | ||||
| UnimplementedNonStreamingChatCompletions       , InvalidRequest       , NOT_IMPLEMENTED ; | ||||
| UnimplementedMultiChoiceChatCompletions        , InvalidRequest       , NOT_IMPLEMENTED ; | ||||
| ChatNotFound                                   , InvalidRequest       , NOT_FOUND   ; | ||||
| InvalidChatSettingDocumentTemplate             , InvalidRequest       , BAD_REQUEST ; | ||||
| InvalidChatCompletionOrgId                     , InvalidRequest       , BAD_REQUEST ; | ||||
| InvalidChatCompletionProjectId                 , InvalidRequest       , BAD_REQUEST ; | ||||
| InvalidChatCompletionApiVersion                , InvalidRequest       , BAD_REQUEST ; | ||||
|   | ||||
| @@ -646,7 +646,7 @@ async fn handle_meili_tools( | ||||
|         } | ||||
|  | ||||
|         let result = match serde_json::from_str(&call.function.arguments) { | ||||
|             Ok(SearchInIndexParameters { index_uid, q }) => process_search_request( | ||||
|             Ok(SearchInIndexParameters { index_uid, q }) => match process_search_request( | ||||
|                 index_scheduler, | ||||
|                 auth_ctrl.clone(), | ||||
|                 search_queue, | ||||
| @@ -655,7 +655,14 @@ async fn handle_meili_tools( | ||||
|                 q, | ||||
|             ) | ||||
|             .await | ||||
|             .map_err(|e| e.to_string()), | ||||
|             { | ||||
|                 Ok(output) => Ok(output), | ||||
|                 Err(err) => { | ||||
|                     let error_text = err.to_string(); | ||||
|                     tx.send_error(&StreamErrorEvent::from_response_error(err)).await?; | ||||
|                     Err(error_text) | ||||
|                 } | ||||
|             }, | ||||
|             Err(err) => Err(err.to_string()), | ||||
|         }; | ||||
|  | ||||
| @@ -664,7 +671,6 @@ async fn handle_meili_tools( | ||||
|                 if report_sources { | ||||
|                     tx.report_sources(resp.clone(), &call.id, &documents).await?; | ||||
|                 } | ||||
|  | ||||
|                 text | ||||
|             } | ||||
|             Err(err) => err, | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| use async_openai::error::{ApiError, OpenAIError}; | ||||
| use async_openai::reqwest_eventsource::Error as EventSourceError; | ||||
| use meilisearch_types::error::ResponseError; | ||||
| use serde::{Deserialize, Serialize}; | ||||
| use uuid::Uuid; | ||||
|  | ||||
| @@ -53,12 +54,13 @@ pub struct StreamError { | ||||
| } | ||||
|  | ||||
| impl StreamErrorEvent { | ||||
|     const ERROR_TYPE: &str = "error"; | ||||
|  | ||||
|     pub async fn from_openai_error(error: OpenAIError) -> Result<Self, reqwest::Error> { | ||||
|         let error_type = "error".to_string(); | ||||
|         match error { | ||||
|             OpenAIError::Reqwest(e) => Ok(StreamErrorEvent { | ||||
|                 event_id: Uuid::new_v4().to_string(), | ||||
|                 r#type: error_type, | ||||
|                 r#type: Self::ERROR_TYPE.to_string(), | ||||
|                 error: StreamError { | ||||
|                     r#type: "internal_reqwest_error".to_string(), | ||||
|                     code: Some("internal".to_string()), | ||||
| @@ -69,7 +71,7 @@ impl StreamErrorEvent { | ||||
|             }), | ||||
|             OpenAIError::ApiError(ApiError { message, r#type, param, code }) => { | ||||
|                 Ok(StreamErrorEvent { | ||||
|                     r#type: error_type, | ||||
|                     r#type: Self::ERROR_TYPE.to_string(), | ||||
|                     event_id: Uuid::new_v4().to_string(), | ||||
|                     error: StreamError { | ||||
|                         r#type: r#type.unwrap_or_else(|| "unknown".to_string()), | ||||
| @@ -82,7 +84,7 @@ impl StreamErrorEvent { | ||||
|             } | ||||
|             OpenAIError::JSONDeserialize(error) => Ok(StreamErrorEvent { | ||||
|                 event_id: Uuid::new_v4().to_string(), | ||||
|                 r#type: error_type, | ||||
|                 r#type: Self::ERROR_TYPE.to_string(), | ||||
|                 error: StreamError { | ||||
|                     r#type: "json_deserialize_error".to_string(), | ||||
|                     code: Some("internal".to_string()), | ||||
| @@ -100,7 +102,7 @@ impl StreamErrorEvent { | ||||
|  | ||||
|                     Ok(StreamErrorEvent { | ||||
|                         event_id: Uuid::new_v4().to_string(), | ||||
|                         r#type: error_type, | ||||
|                         r#type: Self::ERROR_TYPE.to_string(), | ||||
|                         error: StreamError { r#type, code, message, param, event_id: None }, | ||||
|                     }) | ||||
|                 } | ||||
| @@ -111,13 +113,13 @@ impl StreamErrorEvent { | ||||
|  | ||||
|                     Ok(StreamErrorEvent { | ||||
|                         event_id: Uuid::new_v4().to_string(), | ||||
|                         r#type: error_type, | ||||
|                         r#type: Self::ERROR_TYPE.to_string(), | ||||
|                         error: StreamError { r#type, code, message, param, event_id: None }, | ||||
|                     }) | ||||
|                 } | ||||
|                 EventSourceError::Utf8(error) => Ok(StreamErrorEvent { | ||||
|                     event_id: Uuid::new_v4().to_string(), | ||||
|                     r#type: error_type, | ||||
|                     r#type: Self::ERROR_TYPE.to_string(), | ||||
|                     error: StreamError { | ||||
|                         r#type: "invalid_utf8_error".to_string(), | ||||
|                         code: None, | ||||
| @@ -128,7 +130,7 @@ impl StreamErrorEvent { | ||||
|                 }), | ||||
|                 EventSourceError::Parser(error) => Ok(StreamErrorEvent { | ||||
|                     event_id: Uuid::new_v4().to_string(), | ||||
|                     r#type: error_type, | ||||
|                     r#type: Self::ERROR_TYPE.to_string(), | ||||
|                     error: StreamError { | ||||
|                         r#type: "parser_error".to_string(), | ||||
|                         code: None, | ||||
| @@ -139,7 +141,7 @@ impl StreamErrorEvent { | ||||
|                 }), | ||||
|                 EventSourceError::Transport(error) => Ok(StreamErrorEvent { | ||||
|                     event_id: Uuid::new_v4().to_string(), | ||||
|                     r#type: error_type, | ||||
|                     r#type: Self::ERROR_TYPE.to_string(), | ||||
|                     error: StreamError { | ||||
|                         r#type: "transport_error".to_string(), | ||||
|                         code: None, | ||||
| @@ -150,7 +152,7 @@ impl StreamErrorEvent { | ||||
|                 }), | ||||
|                 EventSourceError::InvalidLastEventId(message) => Ok(StreamErrorEvent { | ||||
|                     event_id: Uuid::new_v4().to_string(), | ||||
|                     r#type: error_type, | ||||
|                     r#type: Self::ERROR_TYPE.to_string(), | ||||
|                     error: StreamError { | ||||
|                         r#type: "invalid_last_event_id".to_string(), | ||||
|                         code: None, | ||||
| @@ -161,7 +163,7 @@ impl StreamErrorEvent { | ||||
|                 }), | ||||
|                 EventSourceError::StreamEnded => Ok(StreamErrorEvent { | ||||
|                     event_id: Uuid::new_v4().to_string(), | ||||
|                     r#type: error_type, | ||||
|                     r#type: Self::ERROR_TYPE.to_string(), | ||||
|                     error: StreamError { | ||||
|                         r#type: "stream_ended".to_string(), | ||||
|                         code: None, | ||||
| @@ -173,7 +175,7 @@ impl StreamErrorEvent { | ||||
|             }, | ||||
|             OpenAIError::InvalidArgument(message) => Ok(StreamErrorEvent { | ||||
|                 event_id: Uuid::new_v4().to_string(), | ||||
|                 r#type: error_type, | ||||
|                 r#type: Self::ERROR_TYPE.to_string(), | ||||
|                 error: StreamError { | ||||
|                     r#type: "invalid_argument".to_string(), | ||||
|                     code: None, | ||||
| @@ -184,4 +186,19 @@ impl StreamErrorEvent { | ||||
|             }), | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn from_response_error(error: ResponseError) -> Self { | ||||
|         let ResponseError { code, message, .. } = error; | ||||
|         StreamErrorEvent { | ||||
|             event_id: Uuid::new_v4().to_string(), | ||||
|             r#type: Self::ERROR_TYPE.to_string(), | ||||
|             error: StreamError { | ||||
|                 r#type: "response_error".to_string(), | ||||
|                 code: Some(code.as_str().to_string()), | ||||
|                 message, | ||||
|                 param: None, | ||||
|                 event_id: None, | ||||
|             }, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -9,7 +9,7 @@ use async_openai::types::{ | ||||
|     FunctionCall, FunctionCallStream, Role, | ||||
| }; | ||||
| use bumpalo::Bump; | ||||
| use meilisearch_types::error::ResponseError; | ||||
| use meilisearch_types::error::{Code, ResponseError}; | ||||
| use meilisearch_types::heed::RoTxn; | ||||
| use meilisearch_types::milli::index::ChatConfig; | ||||
| use meilisearch_types::milli::prompt::{Prompt, PromptData}; | ||||
| @@ -237,7 +237,15 @@ pub fn format_documents<'doc>( | ||||
|             Some(doc) => doc, | ||||
|             None => unreachable!("Document with internal ID {docid} not found"), | ||||
|         }; | ||||
|         let text = prompt.render_document(&external_docid, document, &gfid_map, doc_alloc).unwrap(); | ||||
|         let text = match prompt.render_document(&external_docid, document, &gfid_map, doc_alloc) { | ||||
|             Ok(text) => text, | ||||
|             Err(err) => { | ||||
|                 return Err(ResponseError::from_msg( | ||||
|                     err.to_string(), | ||||
|                     Code::InvalidChatSettingDocumentTemplate, | ||||
|                 )) | ||||
|             } | ||||
|         }; | ||||
|         renders.push(text); | ||||
|     } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user