diff --git a/meilisearch-http/src/error.rs b/meilisearch-http/src/error.rs index 857a9e1d9..a40677f97 100644 --- a/meilisearch-http/src/error.rs +++ b/meilisearch-http/src/error.rs @@ -1,6 +1,6 @@ use actix_web as aweb; use aweb::error::{JsonPayloadError, QueryPayloadError}; -use meilisearch_types::document_formats::DocumentFormatError; +use meilisearch_types::document_formats::{DocumentFormatError, PayloadType}; use meilisearch_types::error::{Code, ErrorCode, ResponseError}; use serde_json::Value; use tokio::task::JoinError; @@ -19,6 +19,8 @@ pub enum MeilisearchHttpError { DocumentNotFound(String), #[error("Invalid syntax for the filter parameter: `expected {}, found: {1}`.", .0.join(", "))] InvalidExpression(&'static [&'static str], Value), + #[error("A {0} payload is missing.")] + MissingPayload(PayloadType), #[error("The provided payload reached the size limit.")] PayloadTooLarge, #[error(transparent)] @@ -43,6 +45,7 @@ impl ErrorCode for MeilisearchHttpError { fn error_code(&self) -> Code { match self { MeilisearchHttpError::MissingContentType(_) => Code::MissingContentType, + MeilisearchHttpError::MissingPayload(_) => Code::MissingPayload, MeilisearchHttpError::InvalidContentType(_, _) => Code::InvalidContentType, MeilisearchHttpError::DocumentNotFound(_) => Code::DocumentNotFound, MeilisearchHttpError::InvalidExpression(_, _) => Code::Filter, diff --git a/meilisearch-http/src/routes/indexes/documents.rs b/meilisearch-http/src/routes/indexes/documents.rs index bfb932b5d..716b69862 100644 --- a/meilisearch-http/src/routes/indexes/documents.rs +++ b/meilisearch-http/src/routes/indexes/documents.rs @@ -1,4 +1,4 @@ -use std::io::Cursor; +use std::io::{Cursor, ErrorKind}; use actix_web::http::header::CONTENT_TYPE; use actix_web::web::Data; @@ -228,6 +228,9 @@ async fn document_addition( while let Some(bytes) = body.next().await { buffer.extend_from_slice(&bytes?); } + if buffer.is_empty() { + return Err(MeilisearchHttpError::MissingPayload(format)); + } let reader = Cursor::new(buffer); let documents_count = @@ -239,18 +242,30 @@ async fn document_addition( }; // we NEED to persist the file here because we moved the `udpate_file` in another task. update_file.persist()?; + println!("file has been persisted"); Ok(documents_count) }) .await; let documents_count = match documents_count { Ok(Ok(documents_count)) => documents_count as u64, - Ok(Err(e)) => { - index_scheduler.delete_update_file(uuid)?; - return Err(e); - } + // in this case the file has not possibly be persisted. + Ok(Err(e)) => return Err(e), Err(e) => { - index_scheduler.delete_update_file(uuid)?; + // Here the file MAY have been persisted or not. + // We don't know thus we ignore the file not found error. + match index_scheduler.delete_update_file(uuid) { + Ok(()) => (), + Err(index_scheduler::Error::FileStore(file_store::Error::IoError(e))) + if e.kind() == ErrorKind::NotFound => + { + () + } + Err(e) => { + log::warn!("Unknown error happened while deleting a malformed update file with uuid {uuid}: {e}"); + } + } + // We still want to return the original error to the end user. return Err(e.into()); } }; diff --git a/meilisearch-http/tests/documents/add_documents.rs b/meilisearch-http/tests/documents/add_documents.rs index 8dd3ba39a..b497fbf15 100644 --- a/meilisearch-http/tests/documents/add_documents.rs +++ b/meilisearch-http/tests/documents/add_documents.rs @@ -560,6 +560,7 @@ async fn error_add_missing_payload_ndjson_documents() { let status_code = res.status(); let body = test::read_body(res).await; let response: Value = serde_json::from_slice(&body).unwrap_or_default(); + dbg!(&response); assert_eq!(status_code, 400); assert_eq!(response["message"], json!(r#"A ndjson payload is missing."#)); assert_eq!(response["code"], json!("missing_payload"));