Integrate deserr on the most important routes

This commit is contained in:
Tamo 2022-12-14 13:00:43 +01:00
parent 839b05c43d
commit 50ce0409bc
No known key found for this signature in database
GPG key ID: 20CD8020AFA88D69
21 changed files with 1582 additions and 657 deletions

View file

@ -1,8 +1,11 @@
use std::fmt;
use actix_web::web::Data;
use actix_web::{web, HttpRequest, HttpResponse};
use deserr::{IntoValue, ValuePointerRef};
use index_scheduler::IndexScheduler;
use log::debug;
use meilisearch_types::error::ResponseError;
use meilisearch_types::error::{unwrap_any, Code, ErrorCode, ResponseError};
use meilisearch_types::index_uid::IndexUid;
use meilisearch_types::settings::{settings, Settings, Unchecked};
use meilisearch_types::tasks::KindWithContent;
@ -11,6 +14,7 @@ use serde_json::json;
use crate::analytics::Analytics;
use crate::extractors::authentication::policies::*;
use crate::extractors::authentication::GuardedData;
use crate::extractors::json::ValidatedJson;
use crate::routes::SummarizedTaskView;
#[macro_export]
@ -39,7 +43,7 @@ macro_rules! make_setting_route {
>,
index_uid: web::Path<String>,
) -> Result<HttpResponse, ResponseError> {
let new_settings = Settings { $attr: Setting::Reset, ..Default::default() };
let new_settings = Settings { $attr: Setting::Reset.into(), ..Default::default() };
let allow_index_creation = index_scheduler.filters().allow_index_creation;
let index_uid = IndexUid::try_from(index_uid.into_inner())?.into_inner();
@ -74,8 +78,8 @@ macro_rules! make_setting_route {
let new_settings = Settings {
$attr: match body {
Some(inner_body) => Setting::Set(inner_body),
None => Setting::Reset,
Some(inner_body) => Setting::Set(inner_body).into(),
None => Setting::Reset.into(),
},
..Default::default()
};
@ -208,7 +212,7 @@ make_setting_route!(
"TypoTolerance Updated".to_string(),
json!({
"typo_tolerance": {
"enabled": setting.as_ref().map(|s| !matches!(s.enabled, Setting::Set(false))),
"enabled": setting.as_ref().map(|s| !matches!(s.enabled.into(), Setting::Set(false))),
"disable_on_attributes": setting
.as_ref()
.and_then(|s| s.disable_on_attributes.as_ref().set().map(|m| !m.is_empty())),
@ -424,10 +428,66 @@ generate_configure!(
faceting
);
#[derive(Debug)]
pub struct SettingsDeserrError {
error: String,
code: Code,
}
impl std::fmt::Display for SettingsDeserrError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.error)
}
}
impl std::error::Error for SettingsDeserrError {}
impl ErrorCode for SettingsDeserrError {
fn error_code(&self) -> Code {
self.code
}
}
impl deserr::MergeWithError<SettingsDeserrError> for SettingsDeserrError {
fn merge(
_self_: Option<Self>,
other: SettingsDeserrError,
_merge_location: ValuePointerRef,
) -> Result<Self, Self> {
Err(other)
}
}
impl deserr::DeserializeError for SettingsDeserrError {
fn error<V: IntoValue>(
_self_: Option<Self>,
error: deserr::ErrorKind<V>,
location: ValuePointerRef,
) -> Result<Self, Self> {
let error = unwrap_any(deserr::serde_json::JsonError::error(None, error, location)).0;
let code = match location.first_field() {
Some("displayedAttributes") => Code::InvalidSettingsDisplayedAttributes,
Some("searchableAttributes") => Code::InvalidSettingsSearchableAttributes,
Some("filterableAttributes") => Code::InvalidSettingsFilterableAttributes,
Some("sortableAttributes") => Code::InvalidSettingsSortableAttributes,
Some("rankingRules") => Code::InvalidSettingsRankingRules,
Some("stopWords") => Code::InvalidSettingsStopWords,
Some("synonyms") => Code::InvalidSettingsSynonyms,
Some("distinctAttribute") => Code::InvalidSettingsDistinctAttribute,
Some("typoTolerance") => Code::InvalidSettingsTypoTolerance,
Some("faceting") => Code::InvalidSettingsFaceting,
Some("pagination") => Code::InvalidSettingsPagination,
_ => Code::BadRequest,
};
Err(SettingsDeserrError { error, code })
}
}
pub async fn update_all(
index_scheduler: GuardedData<ActionPolicy<{ actions::SETTINGS_UPDATE }>, Data<IndexScheduler>>,
index_uid: web::Path<String>,
body: web::Json<Settings<Unchecked>>,
body: ValidatedJson<Settings<Unchecked>, SettingsDeserrError>,
req: HttpRequest,
analytics: web::Data<dyn Analytics>,
) -> Result<HttpResponse, ResponseError> {