3023: Update error codes related to tasks cancelation + add canceledBy filter r=Kerollmops a=Kerollmops

<details>This PR changes the error codes [to follow the specification](https://github.com/meilisearch/specifications/pull/195).

 - [x] The `missing_filters` error code is renamed `missing_task_filters` to be more accurate and follow the `invalid_task_*` convention.
 - [x] The error code `invalid_task_uids_filter` is added.
 - [x] The error code `invalid_task_canceled_by_filter` is added.
 - [x] The error code `invalid_task_date_filter` is added.
      -  The error message is the same as for expires_at in the API Key  EXCEPT that it does not explicitly mention that a date must be given in the future.
</details>

Edit by `@loiclec` :
I have added a few more changes into this PR. The related issues are:

- Fixes https://github.com/meilisearch/meilisearch/issues/3029
- Implements https://github.com/meilisearch/meilisearch/issues/3026
- Fixes https://github.com/meilisearch/meilisearch/issues/2940
- Fixes https://github.com/meilisearch/meilisearch/issues/2939

Additionally:
- Fixes a bug where global tasks were returned by `GET /tasks` queries even if the user did not have the `index.*` API key action.
- Rename `originalQuery` to `originalFilters`
- Display `error: null` and `canceledBy: null` in the task views
- Allow using the star operator in the task filters in the `DELETE /tasks` and `POST /tasks/cancel` routes
- Make sure that the index scheduler keeps making progress even when a grave error occurs.


Co-authored-by: Kerollmops <clement@meilisearch.com>
Co-authored-by: Clément Renault <clement@meilisearch.com>
Co-authored-by: Loïc Lecrenier <loic.lecrenier@me.com>
This commit is contained in:
bors[bot]
2022-11-10 10:51:41 +00:00
committed by GitHub
90 changed files with 1129 additions and 362 deletions

View File

@ -147,6 +147,11 @@ pub enum Code {
MissingMasterKey,
NoSpaceLeftOnDevice,
DumpNotFound,
InvalidTaskDate,
InvalidTaskStatuses,
InvalidTaskTypes,
InvalidTaskCanceledBy,
InvalidTaskUids,
TaskNotFound,
TaskDeletionWithEmptyQuery,
TaskCancelationWithEmptyQuery,
@ -238,12 +243,27 @@ impl Code {
MissingMasterKey => {
ErrCode::authentication("missing_master_key", StatusCode::UNAUTHORIZED)
}
InvalidTaskDate => {
ErrCode::invalid("invalid_task_date_filter", StatusCode::BAD_REQUEST)
}
InvalidTaskUids => {
ErrCode::invalid("invalid_task_uids_filter", StatusCode::BAD_REQUEST)
}
InvalidTaskStatuses => {
ErrCode::invalid("invalid_task_statuses_filter", StatusCode::BAD_REQUEST)
}
InvalidTaskTypes => {
ErrCode::invalid("invalid_task_types_filter", StatusCode::BAD_REQUEST)
}
InvalidTaskCanceledBy => {
ErrCode::invalid("invalid_task_canceled_by_filter", StatusCode::BAD_REQUEST)
}
TaskNotFound => ErrCode::invalid("task_not_found", StatusCode::NOT_FOUND),
TaskDeletionWithEmptyQuery => {
ErrCode::invalid("missing_filters", StatusCode::BAD_REQUEST)
ErrCode::invalid("missing_task_filters", StatusCode::BAD_REQUEST)
}
TaskCancelationWithEmptyQuery => {
ErrCode::invalid("missing_filters", StatusCode::BAD_REQUEST)
ErrCode::invalid("missing_task_filters", StatusCode::BAD_REQUEST)
}
DumpNotFound => ErrCode::invalid("dump_not_found", StatusCode::NOT_FOUND),
NoSpaceLeftOnDevice => {

View File

@ -217,12 +217,12 @@ impl KindWithContent {
KindWithContent::TaskCancelation { query, tasks } => Some(Details::TaskCancelation {
matched_tasks: tasks.len(),
canceled_tasks: None,
original_query: query.clone(),
original_filters: query.clone(),
}),
KindWithContent::TaskDeletion { query, tasks } => Some(Details::TaskDeletion {
matched_tasks: tasks.len(),
deleted_tasks: None,
original_query: query.clone(),
original_filters: query.clone(),
}),
KindWithContent::DumpCreation { .. } => None,
KindWithContent::SnapshotCreation => None,
@ -260,12 +260,12 @@ impl KindWithContent {
KindWithContent::TaskCancelation { query, tasks } => Some(Details::TaskCancelation {
matched_tasks: tasks.len(),
canceled_tasks: Some(0),
original_query: query.clone(),
original_filters: query.clone(),
}),
KindWithContent::TaskDeletion { query, tasks } => Some(Details::TaskDeletion {
matched_tasks: tasks.len(),
deleted_tasks: Some(0),
original_query: query.clone(),
original_filters: query.clone(),
}),
KindWithContent::DumpCreation { .. } => None,
KindWithContent::SnapshotCreation => None,
@ -298,12 +298,12 @@ impl From<&KindWithContent> for Option<Details> {
KindWithContent::TaskCancelation { query, tasks } => Some(Details::TaskCancelation {
matched_tasks: tasks.len(),
canceled_tasks: None,
original_query: query.clone(),
original_filters: query.clone(),
}),
KindWithContent::TaskDeletion { query, tasks } => Some(Details::TaskDeletion {
matched_tasks: tasks.len(),
deleted_tasks: None,
original_query: query.clone(),
original_filters: query.clone(),
}),
KindWithContent::DumpCreation { dump_uid, .. } => {
Some(Details::Dump { dump_uid: dump_uid.clone() })
@ -398,7 +398,23 @@ impl Kind {
}
}
}
impl Display for Kind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Kind::DocumentAdditionOrUpdate => write!(f, "documentAdditionOrUpdate"),
Kind::DocumentDeletion => write!(f, "documentDeletion"),
Kind::SettingsUpdate => write!(f, "settingsUpdate"),
Kind::IndexCreation => write!(f, "indexCreation"),
Kind::IndexDeletion => write!(f, "indexDeletion"),
Kind::IndexUpdate => write!(f, "indexUpdate"),
Kind::IndexSwap => write!(f, "indexSwap"),
Kind::TaskCancelation => write!(f, "taskCancelation"),
Kind::TaskDeletion => write!(f, "taskDeletion"),
Kind::DumpCreation => write!(f, "dumpCreation"),
Kind::SnapshotCreation => write!(f, "snapshotCreation"),
}
}
}
impl FromStr for Kind {
type Err = ResponseError;
@ -452,8 +468,8 @@ pub enum Details {
IndexInfo { primary_key: Option<String> },
DocumentDeletion { matched_documents: usize, deleted_documents: Option<u64> },
ClearAll { deleted_documents: Option<u64> },
TaskCancelation { matched_tasks: u64, canceled_tasks: Option<u64>, original_query: String },
TaskDeletion { matched_tasks: u64, deleted_tasks: Option<u64>, original_query: String },
TaskCancelation { matched_tasks: u64, canceled_tasks: Option<u64>, original_filters: String },
TaskDeletion { matched_tasks: u64, deleted_tasks: Option<u64>, original_filters: String },
Dump { dump_uid: String },
IndexSwap { swaps: Vec<IndexSwap> },
}
@ -520,11 +536,11 @@ mod tests {
let details = Details::TaskDeletion {
matched_tasks: 1,
deleted_tasks: None,
original_query: "hello".to_owned(),
original_filters: "hello".to_owned(),
};
let serialised = SerdeJson::<Details>::bytes_encode(&details).unwrap();
let deserialised = SerdeJson::<Details>::bytes_decode(&serialised).unwrap();
meili_snap::snapshot!(format!("{:?}", details), @r###"TaskDeletion { matched_tasks: 1, deleted_tasks: None, original_query: "hello" }"###);
meili_snap::snapshot!(format!("{:?}", deserialised), @r###"TaskDeletion { matched_tasks: 1, deleted_tasks: None, original_query: "hello" }"###);
meili_snap::snapshot!(format!("{:?}", details), @r###"TaskDeletion { matched_tasks: 1, deleted_tasks: None, original_filters: "hello" }"###);
meili_snap::snapshot!(format!("{:?}", deserialised), @r###"TaskDeletion { matched_tasks: 1, deleted_tasks: None, original_filters: "hello" }"###);
}
}