diff --git a/index-scheduler/src/error.rs b/index-scheduler/src/error.rs index 880121f69..7ae96e0b7 100644 --- a/index-scheduler/src/error.rs +++ b/index-scheduler/src/error.rs @@ -15,7 +15,9 @@ pub enum Error { CorruptedTaskQueue, #[error("Task `{0}` not found")] TaskNotFound(TaskId), - + // TODO: Lo: proper error message for this + #[error("Cannot delete all tasks")] + TaskDeletionWithEmptyQuery, // maybe the two next errors are going to move to the frontend #[error("`{0}` is not a status. Available status are")] InvalidStatus(String), @@ -41,6 +43,7 @@ impl ErrorCode for Error { Error::IndexNotFound(_) => Code::IndexNotFound, Error::IndexAlreadyExists(_) => Code::IndexAlreadyExists, Error::TaskNotFound(_) => Code::TaskNotFound, + Error::TaskDeletionWithEmptyQuery => Code::TaskDeletionWithEmptyQuery, Error::InvalidStatus(_) => Code::BadRequest, Error::InvalidKind(_) => Code::BadRequest, diff --git a/index-scheduler/src/lib.rs b/index-scheduler/src/lib.rs index 07d896d7b..f18bd8683 100644 --- a/index-scheduler/src/lib.rs +++ b/index-scheduler/src/lib.rs @@ -56,6 +56,21 @@ impl Default for Query { } impl Query { + /// Return `true` iff every field of the query is set to `None`, such that the query + /// would match all tasks. + pub fn is_empty(&self) -> bool { + matches!( + self, + Query { + limit: None, + from: None, + status: None, + kind: None, + index_uid: None, + uid: None + } + ) + } pub fn with_status(self, status: Status) -> Self { let mut status_vec = self.status.unwrap_or_default(); status_vec.push(status); diff --git a/meilisearch-http/src/routes/tasks.rs b/meilisearch-http/src/routes/tasks.rs index 5b63ed7c5..f1248c8dd 100644 --- a/meilisearch-http/src/routes/tasks.rs +++ b/meilisearch-http/src/routes/tasks.rs @@ -209,6 +209,9 @@ async fn delete_tasks( index_uid, uid, }; + if query.is_empty() { + return Err(index_scheduler::Error::TaskDeletionWithEmptyQuery.into()); + } let filtered_query = filter_out_inaccessible_indexes_from_query(&index_scheduler, &query); @@ -258,6 +261,7 @@ async fn get_tasks( Some(&req), ); + // TODO: Lo: use `filter_out_inaccessible_indexes_from_query` here let mut filters = index_scheduler::Query::default(); // Then we filter on potential indexes and make sure that the search filter diff --git a/meilisearch-types/src/error.rs b/meilisearch-types/src/error.rs index 29705cee0..652e8a660 100644 --- a/meilisearch-types/src/error.rs +++ b/meilisearch-types/src/error.rs @@ -150,6 +150,7 @@ pub enum Code { NoSpaceLeftOnDevice, DumpNotFound, TaskNotFound, + TaskDeletionWithEmptyQuery, PayloadTooLarge, RetrieveDocument, SearchDocuments, @@ -240,6 +241,10 @@ impl Code { ErrCode::authentication("missing_master_key", StatusCode::UNAUTHORIZED) } TaskNotFound => ErrCode::invalid("task_not_found", StatusCode::NOT_FOUND), + // TODO: Lo: find the proper error name & message for this one + TaskDeletionWithEmptyQuery => { + ErrCode::invalid("task_deletion_with_empty_query", StatusCode::BAD_REQUEST) + } DumpNotFound => ErrCode::invalid("dump_not_found", StatusCode::NOT_FOUND), NoSpaceLeftOnDevice => { ErrCode::internal("no_space_left_on_device", StatusCode::INTERNAL_SERVER_ERROR)