Apply suggestion

- remove the payload_error_handler in favor of a PayloadError::from

- merge the two match branch into one

- makes the accepted content type a const instead of recalculating it for every error
This commit is contained in:
Tamo 2021-10-06 11:49:34 +02:00
parent 37b267ffb3
commit 9a1e44dc78
No known key found for this signature in database
GPG Key ID: 20CD8020AFA88D69
3 changed files with 38 additions and 39 deletions

View File

@ -30,6 +30,12 @@ impl ErrorCode for MeilisearchHttpError {
} }
} }
impl From<MeilisearchHttpError> for aweb::Error {
fn from(other: MeilisearchHttpError) -> Self {
aweb::Error::from(ResponseError::from(other))
}
}
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ResponseError { pub struct ResponseError {
@ -125,9 +131,8 @@ impl From<QueryPayloadError> for PayloadError {
} }
} }
pub fn payload_error_handler<E>(err: E) -> ResponseError impl From<PayloadError> for aweb::Error {
where fn from(other: PayloadError) -> Self {
E: Into<PayloadError>, aweb::Error::from(ResponseError::from(other))
{ }
err.into().into()
} }

View File

@ -11,13 +11,14 @@ pub mod routes;
use std::path::Path; use std::path::Path;
use std::time::Duration; use std::time::Duration;
use crate::error::{MeilisearchHttpError, ResponseError}; use crate::error::MeilisearchHttpError;
use crate::extractors::authentication::AuthConfig; use crate::extractors::authentication::AuthConfig;
use actix_web::error::JsonPayloadError; use actix_web::error::JsonPayloadError;
use error::PayloadError;
use http::header::CONTENT_TYPE; use http::header::CONTENT_TYPE;
pub use option::Opt; pub use option::Opt;
use actix_web::web; use actix_web::{web, HttpRequest};
use extractors::authentication::policies::*; use extractors::authentication::policies::*;
use extractors::payload::PayloadConfig; use extractors::payload::PayloadConfig;
@ -102,32 +103,24 @@ pub fn configure_data(config: &mut web::ServiceConfig, data: MeiliSearch, opt: &
.app_data( .app_data(
web::JsonConfig::default() web::JsonConfig::default()
.content_type(|mime| mime == mime::APPLICATION_JSON) .content_type(|mime| mime == mime::APPLICATION_JSON)
.error_handler(|err, req| match err { .error_handler(|err, req: &HttpRequest| match err {
JsonPayloadError::ContentType if req.headers().get(CONTENT_TYPE).is_none() => { JsonPayloadError::ContentType => match req.headers().get(CONTENT_TYPE) {
ResponseError::from(MeilisearchHttpError::MissingContentType(vec![ Some(content_type) => MeilisearchHttpError::InvalidContentType(
mime::APPLICATION_JSON.to_string(), content_type.to_str().unwrap_or("unknown").to_string(),
]))
.into()
}
JsonPayloadError::ContentType => {
ResponseError::from(MeilisearchHttpError::InvalidContentType(
req.headers()
.get(CONTENT_TYPE)
.unwrap()
.to_str()
.unwrap_or("unknown")
.to_string(),
vec![mime::APPLICATION_JSON.to_string()], vec![mime::APPLICATION_JSON.to_string()],
)) )
.into() .into(),
} None => MeilisearchHttpError::MissingContentType(vec![
err => error::payload_error_handler(err).into(), mime::APPLICATION_JSON.to_string(),
])
.into(),
},
err => PayloadError::from(err).into(),
}), }),
) )
.app_data(PayloadConfig::new(http_payload_size_limit)) .app_data(PayloadConfig::new(http_payload_size_limit))
.app_data( .app_data(
web::QueryConfig::default() web::QueryConfig::default().error_handler(|err, _req| PayloadError::from(err).into()),
.error_handler(|err, _req| error::payload_error_handler(err).into()),
); );
} }

View File

@ -6,6 +6,7 @@ use log::debug;
use meilisearch_lib::index_controller::{DocumentAdditionFormat, Update}; use meilisearch_lib::index_controller::{DocumentAdditionFormat, Update};
use meilisearch_lib::milli::update::IndexDocumentsMethod; use meilisearch_lib::milli::update::IndexDocumentsMethod;
use meilisearch_lib::MeiliSearch; use meilisearch_lib::MeiliSearch;
use once_cell::sync::Lazy;
use serde::Deserialize; use serde::Deserialize;
use serde_json::Value; use serde_json::Value;
use tokio::sync::mpsc; use tokio::sync::mpsc;
@ -176,6 +177,13 @@ async fn document_addition(
body: Payload, body: Payload,
method: IndexDocumentsMethod, method: IndexDocumentsMethod,
) -> Result<HttpResponse, ResponseError> { ) -> Result<HttpResponse, ResponseError> {
const ACCEPTED_CONTENT_TYPE: Lazy<Vec<String>> = Lazy::new(|| {
vec![
"application/json".to_string(),
"application/x-ndjson".to_string(),
"application/csv".to_string(),
]
});
let format = match content_type { let format = match content_type {
Some("application/json") => DocumentAdditionFormat::Json, Some("application/json") => DocumentAdditionFormat::Json,
Some("application/x-ndjson") => DocumentAdditionFormat::Ndjson, Some("application/x-ndjson") => DocumentAdditionFormat::Ndjson,
@ -183,21 +191,14 @@ async fn document_addition(
Some(other) => { Some(other) => {
return Err(MeilisearchHttpError::InvalidContentType( return Err(MeilisearchHttpError::InvalidContentType(
other.to_string(), other.to_string(),
vec![ ACCEPTED_CONTENT_TYPE.clone(),
"application/json".to_string(),
"application/x-ndjson".to_string(),
"application/csv".to_string(),
],
) )
.into()) .into())
} }
None => { None => {
return Err(MeilisearchHttpError::MissingContentType(vec![ return Err(
"application/json".to_string(), MeilisearchHttpError::MissingContentType(ACCEPTED_CONTENT_TYPE.clone()).into(),
"application/x-ndjson".to_string(), )
"application/csv".to_string(),
])
.into())
} }
}; };