mirror of
https://github.com/meilisearch/MeiliSearch
synced 2024-11-22 12:54:26 +01:00
Simplify declaration of the error codes
This commit is contained in:
parent
808e184069
commit
2bc2e99ff3
@ -254,14 +254,14 @@ impl<T> From<v5::Setting<T>> for v6::Setting<T> {
|
||||
impl From<v5::ResponseError> for v6::ResponseError {
|
||||
fn from(error: v5::ResponseError) -> Self {
|
||||
let code = match error.error_code.as_ref() {
|
||||
"index_creation_failed" => v6::Code::CreateIndex,
|
||||
"index_creation_failed" => v6::Code::IndexCreationFailed,
|
||||
"index_already_exists" => v6::Code::IndexAlreadyExists,
|
||||
"index_not_found" => v6::Code::IndexNotFound,
|
||||
"invalid_index_uid" => v6::Code::InvalidIndexUid,
|
||||
"invalid_min_word_length_for_typo" => v6::Code::InvalidMinWordLengthForTypo,
|
||||
"invalid_state" => v6::Code::InvalidState,
|
||||
"primary_key_inference_failed" => v6::Code::NoPrimaryKeyCandidateFound,
|
||||
"index_primary_key_already_exists" => v6::Code::PrimaryKeyAlreadyPresent,
|
||||
"primary_key_inference_failed" => v6::Code::IndexPrimaryKeyNoCandidateFound,
|
||||
"index_primary_key_already_exists" => v6::Code::IndexPrimaryKeyAlreadyExists,
|
||||
"max_fields_limit_exceeded" => v6::Code::MaxFieldsLimitExceeded,
|
||||
"missing_document_id" => v6::Code::MissingDocumentId,
|
||||
"invalid_document_id" => v6::Code::InvalidDocumentId,
|
||||
@ -274,16 +274,16 @@ impl From<v5::ResponseError> for v6::ResponseError {
|
||||
"internal" => v6::Code::Internal,
|
||||
"invalid_geo_field" => v6::Code::InvalidDocumentGeoField,
|
||||
"invalid_ranking_rule" => v6::Code::InvalidSettingsRankingRules,
|
||||
"invalid_store_file" => v6::Code::InvalidStore,
|
||||
"invalid_api_key" => v6::Code::InvalidToken,
|
||||
"invalid_store_file" => v6::Code::InvalidStoreFile,
|
||||
"invalid_api_key" => v6::Code::InvalidApiKey,
|
||||
"missing_authorization_header" => v6::Code::MissingAuthorizationHeader,
|
||||
"no_space_left_on_device" => v6::Code::NoSpaceLeftOnDevice,
|
||||
"dump_not_found" => v6::Code::DumpNotFound,
|
||||
"task_not_found" => v6::Code::TaskNotFound,
|
||||
"payload_too_large" => v6::Code::PayloadTooLarge,
|
||||
"unretrievable_document" => v6::Code::DocumentNotFound,
|
||||
"unretrievable_document" => v6::Code::UnretrievableDocument,
|
||||
"unsupported_media_type" => v6::Code::UnsupportedMediaType,
|
||||
"dump_already_processing" => v6::Code::DumpAlreadyInProgress,
|
||||
"dump_already_processing" => v6::Code::DumpAlreadyProcessing,
|
||||
"dump_process_failed" => v6::Code::DumpProcessFailed,
|
||||
"invalid_content_type" => v6::Code::InvalidContentType,
|
||||
"missing_content_type" => v6::Code::MissingContentType,
|
||||
|
@ -139,8 +139,8 @@ impl ErrorCode for Error {
|
||||
match self {
|
||||
Error::IndexNotFound(_) => Code::IndexNotFound,
|
||||
Error::IndexAlreadyExists(_) => Code::IndexAlreadyExists,
|
||||
Error::SwapDuplicateIndexesFound(_) => Code::InvalidDuplicateIndexesFound,
|
||||
Error::SwapDuplicateIndexFound(_) => Code::InvalidDuplicateIndexesFound,
|
||||
Error::SwapDuplicateIndexesFound(_) => Code::InvalidSwapDuplicateIndexFound,
|
||||
Error::SwapDuplicateIndexFound(_) => Code::InvalidSwapDuplicateIndexFound,
|
||||
Error::SwapIndexNotFound(_) => Code::InvalidSwapIndexes,
|
||||
Error::SwapIndexesNotFound(_) => Code::InvalidSwapIndexes,
|
||||
Error::InvalidTaskDate { field, .. } => (*field).into(),
|
||||
@ -150,8 +150,8 @@ impl ErrorCode for Error {
|
||||
Error::InvalidTaskCanceledBy { .. } => Code::InvalidTaskCanceledBy,
|
||||
Error::InvalidIndexUid { .. } => Code::InvalidIndexUid,
|
||||
Error::TaskNotFound(_) => Code::TaskNotFound,
|
||||
Error::TaskDeletionWithEmptyQuery => Code::TaskDeletionWithEmptyQuery,
|
||||
Error::TaskCancelationWithEmptyQuery => Code::TaskCancelationWithEmptyQuery,
|
||||
Error::TaskDeletionWithEmptyQuery => Code::MissingTaskFilters,
|
||||
Error::TaskCancelationWithEmptyQuery => Code::MissingTaskFilters,
|
||||
Error::Dump(e) => e.error_code(),
|
||||
Error::Milli(e) => e.error_code(),
|
||||
Error::ProcessBatchPanicked => Code::Internal,
|
||||
|
@ -1,9 +1,12 @@
|
||||
use std::convert::Infallible;
|
||||
use std::marker::PhantomData;
|
||||
use std::{fmt, io};
|
||||
|
||||
use actix_web::http::StatusCode;
|
||||
use actix_web::{self as aweb, HttpResponseBuilder};
|
||||
use aweb::rt::task::JoinError;
|
||||
use convert_case::Casing;
|
||||
use deserr::{DeserializeError, IntoValue, MergeWithError, ValuePointerRef};
|
||||
use milli::heed::{Error as HeedError, MdbError};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@ -31,7 +34,7 @@ impl ResponseError {
|
||||
Self {
|
||||
code: code.http(),
|
||||
message,
|
||||
error_code: code.err_code().error_name.to_string(),
|
||||
error_code: code.err_code().error_name,
|
||||
error_type: code.type_(),
|
||||
error_link: code.url(),
|
||||
}
|
||||
@ -48,7 +51,7 @@ impl std::error::Error for ResponseError {}
|
||||
|
||||
impl<T> From<T> for ResponseError
|
||||
where
|
||||
T: ErrorCode,
|
||||
T: std::error::Error + ErrorCode,
|
||||
{
|
||||
fn from(other: T) -> Self {
|
||||
Self::from_msg(other.to_string(), other.error_code())
|
||||
@ -66,7 +69,7 @@ impl aweb::error::ResponseError for ResponseError {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ErrorCode: std::error::Error {
|
||||
pub trait ErrorCode {
|
||||
fn error_code(&self) -> Code;
|
||||
|
||||
/// returns the HTTP status code associated with the error
|
||||
@ -111,461 +114,188 @@ impl fmt::Display for ErrorType {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Code {
|
||||
// error related to your setup
|
||||
IoError,
|
||||
NoSpaceLeftOnDevice,
|
||||
TooManyOpenFiles,
|
||||
|
||||
// index related error
|
||||
CreateIndex,
|
||||
IndexAlreadyExists,
|
||||
InvalidIndexPrimaryKey,
|
||||
IndexNotFound,
|
||||
InvalidIndexUid,
|
||||
MissingIndexUid,
|
||||
InvalidMinWordLengthForTypo,
|
||||
InvalidIndexLimit,
|
||||
InvalidIndexOffset,
|
||||
|
||||
DuplicateIndexFound,
|
||||
|
||||
// invalid state error
|
||||
InvalidState,
|
||||
NoPrimaryKeyCandidateFound,
|
||||
MultiplePrimaryKeyCandidatesFound,
|
||||
PrimaryKeyAlreadyPresent,
|
||||
|
||||
MaxFieldsLimitExceeded,
|
||||
MissingDocumentId,
|
||||
InvalidDocumentId,
|
||||
|
||||
// Invalid swap-indexes
|
||||
InvalidSwapIndexes,
|
||||
InvalidDuplicateIndexesFound,
|
||||
|
||||
// Invalid settings update request
|
||||
InvalidSettingsDisplayedAttributes,
|
||||
InvalidSettingsSearchableAttributes,
|
||||
InvalidSettingsFilterableAttributes,
|
||||
InvalidSettingsSortableAttributes,
|
||||
InvalidSettingsRankingRules,
|
||||
InvalidSettingsStopWords,
|
||||
InvalidSettingsSynonyms,
|
||||
InvalidSettingsDistinctAttribute,
|
||||
InvalidSettingsTypoTolerance,
|
||||
InvalidSettingsFaceting,
|
||||
InvalidSettingsPagination,
|
||||
|
||||
// Invalid search request
|
||||
InvalidSearchQ,
|
||||
InvalidSearchOffset,
|
||||
InvalidSearchLimit,
|
||||
InvalidSearchPage,
|
||||
InvalidSearchHitsPerPage,
|
||||
InvalidSearchAttributesToRetrieve,
|
||||
InvalidSearchAttributesToCrop,
|
||||
InvalidSearchCropLength,
|
||||
InvalidSearchAttributesToHighlight,
|
||||
InvalidSearchShowMatchesPosition,
|
||||
InvalidSearchFilter,
|
||||
InvalidSearchSort,
|
||||
InvalidSearchFacets,
|
||||
InvalidSearchHighlightPreTag,
|
||||
InvalidSearchHighlightPostTag,
|
||||
InvalidSearchCropMarker,
|
||||
InvalidSearchMatchingStrategy,
|
||||
|
||||
// Related to the tasks
|
||||
InvalidTaskUids,
|
||||
InvalidTaskTypes,
|
||||
InvalidTaskStatuses,
|
||||
InvalidTaskCanceledBy,
|
||||
InvalidTaskLimit,
|
||||
InvalidTaskFrom,
|
||||
InvalidTaskBeforeEnqueuedAt,
|
||||
InvalidTaskAfterEnqueuedAt,
|
||||
InvalidTaskBeforeStartedAt,
|
||||
InvalidTaskAfterStartedAt,
|
||||
InvalidTaskBeforeFinishedAt,
|
||||
InvalidTaskAfterFinishedAt,
|
||||
|
||||
// Documents API
|
||||
InvalidDocumentFields,
|
||||
InvalidDocumentLimit,
|
||||
InvalidDocumentOffset,
|
||||
|
||||
BadParameter,
|
||||
BadRequest,
|
||||
DatabaseSizeLimitReached,
|
||||
DocumentNotFound,
|
||||
Internal,
|
||||
InvalidDocumentGeoField,
|
||||
InvalidStore,
|
||||
InvalidToken,
|
||||
MissingAuthorizationHeader,
|
||||
MissingMasterKey,
|
||||
DumpNotFound,
|
||||
TaskNotFound,
|
||||
TaskDeletionWithEmptyQuery,
|
||||
TaskCancelationWithEmptyQuery,
|
||||
PayloadTooLarge,
|
||||
UnsupportedMediaType,
|
||||
|
||||
DumpAlreadyInProgress,
|
||||
DumpProcessFailed,
|
||||
// Only used when importing a dump
|
||||
UnretrievableErrorCode,
|
||||
|
||||
InvalidContentType,
|
||||
MissingContentType,
|
||||
MalformedPayload,
|
||||
MissingPayload,
|
||||
|
||||
ApiKeyNotFound,
|
||||
|
||||
MissingApiKeyActions,
|
||||
MissingApiKeyExpiresAt,
|
||||
MissingApiKeyIndexes,
|
||||
|
||||
InvalidApiKeyOffset,
|
||||
InvalidApiKeyLimit,
|
||||
InvalidApiKeyActions,
|
||||
InvalidApiKeyIndexes,
|
||||
InvalidApiKeyExpiresAt,
|
||||
InvalidApiKeyDescription,
|
||||
InvalidApiKeyName,
|
||||
InvalidApiKeyUid,
|
||||
ImmutableField,
|
||||
ApiKeyAlreadyExists,
|
||||
}
|
||||
|
||||
impl Code {
|
||||
/// associate a `Code` variant to the actual ErrCode
|
||||
fn err_code(&self) -> ErrCode {
|
||||
use Code::*;
|
||||
|
||||
match self {
|
||||
// related to the setup
|
||||
IoError => ErrCode::system("io_error", StatusCode::INTERNAL_SERVER_ERROR),
|
||||
TooManyOpenFiles => {
|
||||
ErrCode::system("too_many_open_files", StatusCode::INTERNAL_SERVER_ERROR)
|
||||
macro_rules! make_error_codes {
|
||||
($($code_ident:ident, $err_type:ident, $status:ident);*) => {
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Code {
|
||||
$($code_ident),*
|
||||
}
|
||||
impl Code {
|
||||
/// associate a `Code` variant to the actual ErrCode
|
||||
fn err_code(&self) -> ErrCode {
|
||||
match self {
|
||||
$(
|
||||
Code::$code_ident => {
|
||||
ErrCode::$err_type( stringify!($code_ident).to_case(convert_case::Case::Snake), StatusCode::$status)
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
NoSpaceLeftOnDevice => {
|
||||
ErrCode::system("no_space_left_on_device", StatusCode::INTERNAL_SERVER_ERROR)
|
||||
/// return the HTTP status code associated with the `Code`
|
||||
fn http(&self) -> StatusCode {
|
||||
self.err_code().status_code
|
||||
}
|
||||
|
||||
// index related errors
|
||||
// create index is thrown on internal error while creating an index.
|
||||
CreateIndex => {
|
||||
ErrCode::internal("index_creation_failed", StatusCode::INTERNAL_SERVER_ERROR)
|
||||
}
|
||||
IndexAlreadyExists => ErrCode::invalid("index_already_exists", StatusCode::CONFLICT),
|
||||
// thrown when requesting an unexisting index
|
||||
IndexNotFound => ErrCode::invalid("index_not_found", StatusCode::NOT_FOUND),
|
||||
InvalidIndexUid => ErrCode::invalid("invalid_index_uid", StatusCode::BAD_REQUEST),
|
||||
MissingIndexUid => ErrCode::invalid("missing_index_uid", StatusCode::BAD_REQUEST),
|
||||
InvalidIndexPrimaryKey => {
|
||||
ErrCode::invalid("invalid_index_primary_key", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidIndexLimit => ErrCode::invalid("invalid_index_limit", StatusCode::BAD_REQUEST),
|
||||
InvalidIndexOffset => ErrCode::invalid("invalid_index_offset", StatusCode::BAD_REQUEST),
|
||||
|
||||
// invalid state error
|
||||
InvalidState => ErrCode::internal("invalid_state", StatusCode::INTERNAL_SERVER_ERROR),
|
||||
// thrown when no primary key has been set
|
||||
NoPrimaryKeyCandidateFound => {
|
||||
ErrCode::invalid("index_primary_key_no_candidate_found", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
MultiplePrimaryKeyCandidatesFound => ErrCode::invalid(
|
||||
"index_primary_key_multiple_candidates_found",
|
||||
StatusCode::BAD_REQUEST,
|
||||
),
|
||||
// error thrown when trying to set an already existing primary key
|
||||
PrimaryKeyAlreadyPresent => {
|
||||
ErrCode::invalid("index_primary_key_already_exists", StatusCode::BAD_REQUEST)
|
||||
/// return error name, used as error code
|
||||
fn name(&self) -> String {
|
||||
self.err_code().error_name.to_string()
|
||||
}
|
||||
|
||||
// invalid database
|
||||
InvalidStore => {
|
||||
ErrCode::internal("invalid_store_file", StatusCode::INTERNAL_SERVER_ERROR)
|
||||
/// return the error type
|
||||
fn type_(&self) -> String {
|
||||
self.err_code().error_type.to_string()
|
||||
}
|
||||
|
||||
// invalid document
|
||||
MaxFieldsLimitExceeded => {
|
||||
ErrCode::invalid("max_fields_limit_exceeded", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
MissingDocumentId => ErrCode::invalid("missing_document_id", StatusCode::BAD_REQUEST),
|
||||
InvalidDocumentId => ErrCode::invalid("invalid_document_id", StatusCode::BAD_REQUEST),
|
||||
|
||||
BadParameter => ErrCode::invalid("bad_parameter", StatusCode::BAD_REQUEST),
|
||||
BadRequest => ErrCode::invalid("bad_request", StatusCode::BAD_REQUEST),
|
||||
DatabaseSizeLimitReached => {
|
||||
ErrCode::internal("database_size_limit_reached", StatusCode::INTERNAL_SERVER_ERROR)
|
||||
}
|
||||
DocumentNotFound => ErrCode::invalid("document_not_found", StatusCode::NOT_FOUND),
|
||||
Internal => ErrCode::internal("internal", StatusCode::INTERNAL_SERVER_ERROR),
|
||||
InvalidDocumentGeoField => {
|
||||
ErrCode::invalid("invalid_document_geo_field", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidToken => ErrCode::authentication("invalid_api_key", StatusCode::FORBIDDEN),
|
||||
MissingAuthorizationHeader => {
|
||||
ErrCode::authentication("missing_authorization_header", StatusCode::UNAUTHORIZED)
|
||||
}
|
||||
MissingMasterKey => {
|
||||
ErrCode::authentication("missing_master_key", StatusCode::UNAUTHORIZED)
|
||||
}
|
||||
TaskNotFound => ErrCode::invalid("task_not_found", StatusCode::NOT_FOUND),
|
||||
TaskDeletionWithEmptyQuery => {
|
||||
ErrCode::invalid("missing_task_filters", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
TaskCancelationWithEmptyQuery => {
|
||||
ErrCode::invalid("missing_task_filters", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
DumpNotFound => ErrCode::invalid("dump_not_found", StatusCode::NOT_FOUND),
|
||||
PayloadTooLarge => ErrCode::invalid("payload_too_large", StatusCode::PAYLOAD_TOO_LARGE),
|
||||
UnsupportedMediaType => {
|
||||
ErrCode::invalid("unsupported_media_type", StatusCode::UNSUPPORTED_MEDIA_TYPE)
|
||||
}
|
||||
|
||||
// error related to dump
|
||||
DumpAlreadyInProgress => {
|
||||
ErrCode::invalid("dump_already_processing", StatusCode::CONFLICT)
|
||||
}
|
||||
DumpProcessFailed => {
|
||||
ErrCode::internal("dump_process_failed", StatusCode::INTERNAL_SERVER_ERROR)
|
||||
}
|
||||
MissingContentType => {
|
||||
ErrCode::invalid("missing_content_type", StatusCode::UNSUPPORTED_MEDIA_TYPE)
|
||||
}
|
||||
MalformedPayload => ErrCode::invalid("malformed_payload", StatusCode::BAD_REQUEST),
|
||||
InvalidContentType => {
|
||||
ErrCode::invalid("invalid_content_type", StatusCode::UNSUPPORTED_MEDIA_TYPE)
|
||||
}
|
||||
MissingPayload => ErrCode::invalid("missing_payload", StatusCode::BAD_REQUEST),
|
||||
// This one can only happen when importing a dump and encountering an unknown code in the task queue.
|
||||
UnretrievableErrorCode => {
|
||||
ErrCode::invalid("unretrievable_error_code", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
|
||||
// error related to keys
|
||||
ApiKeyNotFound => ErrCode::invalid("api_key_not_found", StatusCode::NOT_FOUND),
|
||||
|
||||
MissingApiKeyExpiresAt => {
|
||||
ErrCode::invalid("missing_api_key_expires_at", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
|
||||
MissingApiKeyActions => {
|
||||
ErrCode::invalid("missing_api_key_actions", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
|
||||
MissingApiKeyIndexes => {
|
||||
ErrCode::invalid("missing_api_key_indexes", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
|
||||
InvalidApiKeyOffset => {
|
||||
ErrCode::invalid("invalid_api_key_offset", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidApiKeyLimit => {
|
||||
ErrCode::invalid("invalid_api_key_limit", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidApiKeyActions => {
|
||||
ErrCode::invalid("invalid_api_key_actions", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidApiKeyIndexes => {
|
||||
ErrCode::invalid("invalid_api_key_indexes", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidApiKeyExpiresAt => {
|
||||
ErrCode::invalid("invalid_api_key_expires_at", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidApiKeyDescription => {
|
||||
ErrCode::invalid("invalid_api_key_description", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidApiKeyName => ErrCode::invalid("invalid_api_key_name", StatusCode::BAD_REQUEST),
|
||||
InvalidApiKeyUid => ErrCode::invalid("invalid_api_key_uid", StatusCode::BAD_REQUEST),
|
||||
ApiKeyAlreadyExists => ErrCode::invalid("api_key_already_exists", StatusCode::CONFLICT),
|
||||
ImmutableField => ErrCode::invalid("immutable_field", StatusCode::BAD_REQUEST),
|
||||
InvalidMinWordLengthForTypo => {
|
||||
ErrCode::invalid("invalid_min_word_length_for_typo", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
DuplicateIndexFound => {
|
||||
ErrCode::invalid("duplicate_index_found", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
|
||||
// Swap indexes error
|
||||
InvalidSwapIndexes => ErrCode::invalid("invalid_swap_indexes", StatusCode::BAD_REQUEST),
|
||||
InvalidDuplicateIndexesFound => {
|
||||
ErrCode::invalid("invalid_swap_duplicate_index_found", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
|
||||
// Invalid settings
|
||||
InvalidSettingsDisplayedAttributes => {
|
||||
ErrCode::invalid("invalid_settings_displayed_attributes", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidSettingsSearchableAttributes => {
|
||||
ErrCode::invalid("invalid_settings_searchable_attributes", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidSettingsFilterableAttributes => {
|
||||
ErrCode::invalid("invalid_settings_filterable_attributes", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidSettingsSortableAttributes => {
|
||||
ErrCode::invalid("invalid_settings_sortable_attributes", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidSettingsRankingRules => {
|
||||
ErrCode::invalid("invalid_settings_ranking_rules", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidSettingsStopWords => {
|
||||
ErrCode::invalid("invalid_settings_stop_words", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidSettingsSynonyms => {
|
||||
ErrCode::invalid("invalid_settings_synonyms", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidSettingsDistinctAttribute => {
|
||||
ErrCode::invalid("invalid_settings_distinct_attribute", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidSettingsTypoTolerance => {
|
||||
ErrCode::invalid("invalid_settings_typo_tolerance", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidSettingsFaceting => {
|
||||
ErrCode::invalid("invalid_settings_faceting", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidSettingsPagination => {
|
||||
ErrCode::invalid("invalid_settings_pagination", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
|
||||
// Invalid search
|
||||
InvalidSearchQ => ErrCode::invalid("invalid_search_q", StatusCode::BAD_REQUEST),
|
||||
InvalidSearchOffset => {
|
||||
ErrCode::invalid("invalid_search_offset", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidSearchLimit => ErrCode::invalid("invalid_search_limit", StatusCode::BAD_REQUEST),
|
||||
InvalidSearchPage => ErrCode::invalid("invalid_search_page", StatusCode::BAD_REQUEST),
|
||||
InvalidSearchHitsPerPage => {
|
||||
ErrCode::invalid("invalid_search_hits_per_page", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidSearchAttributesToRetrieve => {
|
||||
ErrCode::invalid("invalid_search_attributes_to_retrieve", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidSearchAttributesToCrop => {
|
||||
ErrCode::invalid("invalid_search_attributes_to_crop", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidSearchCropLength => {
|
||||
ErrCode::invalid("invalid_search_crop_length", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidSearchAttributesToHighlight => {
|
||||
ErrCode::invalid("invalid_search_attributes_to_highlight", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidSearchShowMatchesPosition => {
|
||||
ErrCode::invalid("invalid_search_show_matches_position", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidSearchFilter => {
|
||||
ErrCode::invalid("invalid_search_filter", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidSearchSort => ErrCode::invalid("invalid_search_sort", StatusCode::BAD_REQUEST),
|
||||
InvalidSearchFacets => {
|
||||
ErrCode::invalid("invalid_search_facets", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidSearchHighlightPreTag => {
|
||||
ErrCode::invalid("invalid_search_highlight_pre_tag", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidSearchHighlightPostTag => {
|
||||
ErrCode::invalid("invalid_search_highlight_post_tag", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidSearchCropMarker => {
|
||||
ErrCode::invalid("invalid_search_crop_marker", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidSearchMatchingStrategy => {
|
||||
ErrCode::invalid("invalid_search_matching_strategy", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
|
||||
// Related to the tasks
|
||||
InvalidTaskUids => ErrCode::invalid("invalid_task_uids", StatusCode::BAD_REQUEST),
|
||||
InvalidTaskTypes => ErrCode::invalid("invalid_task_types", StatusCode::BAD_REQUEST),
|
||||
InvalidTaskStatuses => {
|
||||
ErrCode::invalid("invalid_task_statuses", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidTaskCanceledBy => {
|
||||
ErrCode::invalid("invalid_task_canceled_by", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidTaskLimit => ErrCode::invalid("invalid_task_limit", StatusCode::BAD_REQUEST),
|
||||
InvalidTaskFrom => ErrCode::invalid("invalid_task_from", StatusCode::BAD_REQUEST),
|
||||
InvalidTaskBeforeEnqueuedAt => {
|
||||
ErrCode::invalid("invalid_task_before_enqueued_at", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidTaskAfterEnqueuedAt => {
|
||||
ErrCode::invalid("invalid_task_after_enqueued_at", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidTaskBeforeStartedAt => {
|
||||
ErrCode::invalid("invalid_task_before_started_at", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidTaskAfterStartedAt => {
|
||||
ErrCode::invalid("invalid_task_after_started_at", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidTaskBeforeFinishedAt => {
|
||||
ErrCode::invalid("invalid_task_before_finished_at", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidTaskAfterFinishedAt => {
|
||||
ErrCode::invalid("invalid_task_after_finished_at", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
|
||||
InvalidDocumentFields => {
|
||||
ErrCode::invalid("invalid_document_fields", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidDocumentLimit => {
|
||||
ErrCode::invalid("invalid_document_limit", StatusCode::BAD_REQUEST)
|
||||
}
|
||||
InvalidDocumentOffset => {
|
||||
ErrCode::invalid("invalid_document_offset", StatusCode::BAD_REQUEST)
|
||||
/// return the doc url associated with the error
|
||||
fn url(&self) -> String {
|
||||
format!(
|
||||
"https://docs.meilisearch.com/errors#{}",
|
||||
self.name().to_case(convert_case::Case::Kebab)
|
||||
)
|
||||
}
|
||||
}
|
||||
pub mod deserr_codes {
|
||||
use super::{Code, ErrorCode};
|
||||
$(
|
||||
#[derive(Default)]
|
||||
pub struct $code_ident;
|
||||
impl ErrorCode for $code_ident {
|
||||
fn error_code(&self) -> Code {
|
||||
Code::$code_ident
|
||||
}
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
/// return the HTTP status code associated with the `Code`
|
||||
fn http(&self) -> StatusCode {
|
||||
self.err_code().status_code
|
||||
}
|
||||
|
||||
/// return error name, used as error code
|
||||
fn name(&self) -> String {
|
||||
self.err_code().error_name.to_string()
|
||||
}
|
||||
|
||||
/// return the error type
|
||||
fn type_(&self) -> String {
|
||||
self.err_code().error_type.to_string()
|
||||
}
|
||||
|
||||
/// return the doc url associated with the error
|
||||
fn url(&self) -> String {
|
||||
format!(
|
||||
"https://docs.meilisearch.com/errors#{}",
|
||||
self.name().to_case(convert_case::Case::Kebab)
|
||||
)
|
||||
}
|
||||
}
|
||||
make_error_codes! {
|
||||
ApiKeyAlreadyExists , invalid , CONFLICT ;
|
||||
ApiKeyNotFound , invalid , NOT_FOUND ;
|
||||
BadParameter , invalid , BAD_REQUEST;
|
||||
BadRequest , invalid , BAD_REQUEST;
|
||||
DatabaseSizeLimitReached , internal , INTERNAL_SERVER_ERROR;
|
||||
DocumentNotFound , invalid , NOT_FOUND;
|
||||
DumpAlreadyProcessing , invalid , CONFLICT;
|
||||
DumpNotFound , invalid , NOT_FOUND;
|
||||
DumpProcessFailed , internal , INTERNAL_SERVER_ERROR;
|
||||
DuplicateIndexFound , invalid , BAD_REQUEST;
|
||||
ImmutableField , invalid , BAD_REQUEST;
|
||||
IndexAlreadyExists , invalid , CONFLICT ;
|
||||
IndexCreationFailed , internal , INTERNAL_SERVER_ERROR;
|
||||
IndexNotFound , invalid , NOT_FOUND;
|
||||
IndexPrimaryKeyAlreadyExists , invalid , BAD_REQUEST ;
|
||||
IndexPrimaryKeyNoCandidateFound , invalid , BAD_REQUEST ;
|
||||
IndexPrimaryKeyMultipleCandidatesFound, invalid , BAD_REQUEST;
|
||||
Internal , internal , INTERNAL_SERVER_ERROR ;
|
||||
InvalidApiKeyActions , invalid , BAD_REQUEST ;
|
||||
InvalidApiKeyDescription , invalid , BAD_REQUEST ;
|
||||
InvalidApiKeyExpiresAt , invalid , BAD_REQUEST ;
|
||||
InvalidApiKeyIndexes , invalid , BAD_REQUEST ;
|
||||
InvalidApiKeyLimit , invalid , BAD_REQUEST ;
|
||||
InvalidApiKeyName , invalid , BAD_REQUEST ;
|
||||
InvalidApiKeyOffset , invalid , BAD_REQUEST ;
|
||||
InvalidApiKeyUid , invalid , BAD_REQUEST ;
|
||||
InvalidApiKey , authentication, FORBIDDEN ;
|
||||
InvalidContentType , invalid , UNSUPPORTED_MEDIA_TYPE ;
|
||||
InvalidDocumentFields , invalid , BAD_REQUEST ;
|
||||
InvalidDocumentGeoField , invalid , BAD_REQUEST ;
|
||||
InvalidDocumentId , invalid , BAD_REQUEST ;
|
||||
InvalidDocumentLimit , invalid , BAD_REQUEST ;
|
||||
InvalidDocumentOffset , invalid , BAD_REQUEST ;
|
||||
InvalidIndexLimit , invalid , BAD_REQUEST ;
|
||||
InvalidIndexOffset , invalid , BAD_REQUEST ;
|
||||
InvalidIndexPrimaryKey , invalid , BAD_REQUEST ;
|
||||
InvalidIndexUid , invalid , BAD_REQUEST ;
|
||||
InvalidMinWordLengthForTypo , invalid , BAD_REQUEST ;
|
||||
InvalidRankingRule , invalid , BAD_REQUEST ;
|
||||
InvalidSearchAttributesToCrop , invalid , BAD_REQUEST ;
|
||||
InvalidSearchAttributesToHighlight , invalid , BAD_REQUEST ;
|
||||
InvalidSearchAttributesToRetrieve , invalid , BAD_REQUEST ;
|
||||
InvalidSearchCropLength , invalid , BAD_REQUEST ;
|
||||
InvalidSearchCropMarker , invalid , BAD_REQUEST ;
|
||||
InvalidSearchFacets , invalid , BAD_REQUEST ;
|
||||
InvalidSearchFilter , invalid , BAD_REQUEST ;
|
||||
InvalidSearchHighlightPostTag , invalid , BAD_REQUEST ;
|
||||
InvalidSearchHighlightPreTag , invalid , BAD_REQUEST ;
|
||||
InvalidSearchHitsPerPage , invalid , BAD_REQUEST ;
|
||||
InvalidSearchLimit , invalid , BAD_REQUEST ;
|
||||
InvalidSearchMatchingStrategy , invalid , BAD_REQUEST ;
|
||||
InvalidSearchOffset , invalid , BAD_REQUEST ;
|
||||
InvalidSearchPage , invalid , BAD_REQUEST ;
|
||||
InvalidSearchQ , invalid , BAD_REQUEST ;
|
||||
InvalidSearchShowMatchesPosition , invalid , BAD_REQUEST ;
|
||||
InvalidSearchSort , invalid , BAD_REQUEST ;
|
||||
InvalidSettingsDisplayedAttributes , invalid , BAD_REQUEST ;
|
||||
InvalidSettingsDistinctAttribute , invalid , BAD_REQUEST ;
|
||||
InvalidSettingsFaceting , invalid , BAD_REQUEST ;
|
||||
InvalidSettingsFilterableAttributes , invalid , BAD_REQUEST ;
|
||||
InvalidSettingsPagination , invalid , BAD_REQUEST ;
|
||||
InvalidSettingsRankingRules , invalid , BAD_REQUEST ;
|
||||
InvalidSettingsSearchableAttributes , invalid , BAD_REQUEST ;
|
||||
InvalidSettingsSortableAttributes , invalid , BAD_REQUEST ;
|
||||
InvalidSettingsStopWords , invalid , BAD_REQUEST ;
|
||||
InvalidSettingsSynonyms , invalid , BAD_REQUEST ;
|
||||
InvalidSettingsTypoTolerance , invalid , BAD_REQUEST ;
|
||||
InvalidState , internal , INTERNAL_SERVER_ERROR ;
|
||||
InvalidStoreFile , internal , INTERNAL_SERVER_ERROR ;
|
||||
InvalidSwapDuplicateIndexFound , invalid , BAD_REQUEST ;
|
||||
InvalidSwapIndexes , invalid , BAD_REQUEST ;
|
||||
InvalidTaskAfterEnqueuedAt , invalid , BAD_REQUEST ;
|
||||
InvalidTaskAfterFinishedAt , invalid , BAD_REQUEST ;
|
||||
InvalidTaskAfterStartedAt , invalid , BAD_REQUEST ;
|
||||
InvalidTaskBeforeEnqueuedAt , invalid , BAD_REQUEST ;
|
||||
InvalidTaskBeforeFinishedAt , invalid , BAD_REQUEST ;
|
||||
InvalidTaskBeforeStartedAt , invalid , BAD_REQUEST ;
|
||||
InvalidTaskCanceledBy , invalid , BAD_REQUEST ;
|
||||
InvalidTaskFrom , invalid , BAD_REQUEST ;
|
||||
InvalidTaskLimit , invalid , BAD_REQUEST ;
|
||||
InvalidTaskStatuses , invalid , BAD_REQUEST ;
|
||||
InvalidTaskTypes , invalid , BAD_REQUEST ;
|
||||
InvalidTaskUids , invalid , BAD_REQUEST ;
|
||||
IoError , system , UNPROCESSABLE_ENTITY;
|
||||
MalformedPayload , invalid , BAD_REQUEST ;
|
||||
MaxFieldsLimitExceeded , invalid , BAD_REQUEST ;
|
||||
MissingApiKeyActions , invalid , BAD_REQUEST ;
|
||||
MissingApiKeyExpiresAt , invalid , BAD_REQUEST ;
|
||||
MissingApiKeyIndexes , invalid , BAD_REQUEST ;
|
||||
MissingAuthorizationHeader , authentication, UNAUTHORIZED ;
|
||||
MissingContentType , invalid , UNSUPPORTED_MEDIA_TYPE ;
|
||||
MissingDocumentId , invalid , BAD_REQUEST ;
|
||||
MissingIndexUid , invalid , BAD_REQUEST ;
|
||||
MissingMasterKey , authentication, UNAUTHORIZED ;
|
||||
MissingPayload , invalid , BAD_REQUEST ;
|
||||
MissingTaskFilters , invalid , BAD_REQUEST ;
|
||||
NoSpaceLeftOnDevice , system , UNPROCESSABLE_ENTITY;
|
||||
PayloadTooLarge , invalid , PAYLOAD_TOO_LARGE ;
|
||||
TaskNotFound , invalid , NOT_FOUND ;
|
||||
TooManyOpenFiles , system , UNPROCESSABLE_ENTITY ;
|
||||
UnretrievableDocument , internal , BAD_REQUEST ;
|
||||
UnretrievableErrorCode , invalid , BAD_REQUEST ;
|
||||
UnsupportedMediaType , invalid , UNSUPPORTED_MEDIA_TYPE
|
||||
}
|
||||
|
||||
/// Internal structure providing a convenient way to create error codes
|
||||
struct ErrCode {
|
||||
status_code: StatusCode,
|
||||
error_type: ErrorType,
|
||||
error_name: &'static str,
|
||||
error_name: String,
|
||||
}
|
||||
|
||||
impl ErrCode {
|
||||
fn authentication(error_name: &'static str, status_code: StatusCode) -> ErrCode {
|
||||
fn authentication(error_name: String, status_code: StatusCode) -> ErrCode {
|
||||
ErrCode { status_code, error_name, error_type: ErrorType::AuthenticationError }
|
||||
}
|
||||
|
||||
fn internal(error_name: &'static str, status_code: StatusCode) -> ErrCode {
|
||||
fn internal(error_name: String, status_code: StatusCode) -> ErrCode {
|
||||
ErrCode { status_code, error_name, error_type: ErrorType::InternalError }
|
||||
}
|
||||
|
||||
fn invalid(error_name: &'static str, status_code: StatusCode) -> ErrCode {
|
||||
fn invalid(error_name: String, status_code: StatusCode) -> ErrCode {
|
||||
ErrCode { status_code, error_name, error_type: ErrorType::InvalidRequestError }
|
||||
}
|
||||
|
||||
fn system(error_name: &'static str, status_code: StatusCode) -> ErrCode {
|
||||
fn system(error_name: String, status_code: StatusCode) -> ErrCode {
|
||||
ErrCode { status_code, error_name, error_type: ErrorType::System }
|
||||
}
|
||||
}
|
||||
@ -591,7 +321,7 @@ impl ErrorCode for milli::Error {
|
||||
| UserError::DocumentLimitReached
|
||||
| UserError::AccessingSoftDeletedDocument { .. }
|
||||
| UserError::UnknownInternalDocumentId { .. } => Code::Internal,
|
||||
UserError::InvalidStoreFile => Code::InvalidStore,
|
||||
UserError::InvalidStoreFile => Code::InvalidStoreFile,
|
||||
UserError::NoSpaceLeftOnDevice => Code::NoSpaceLeftOnDevice,
|
||||
UserError::MaxDatabaseSizeReached => Code::DatabaseSizeLimitReached,
|
||||
UserError::AttributeLimitReached => Code::MaxFieldsLimitExceeded,
|
||||
@ -600,15 +330,15 @@ impl ErrorCode for milli::Error {
|
||||
UserError::InvalidDocumentId { .. } | UserError::TooManyDocumentIds { .. } => {
|
||||
Code::InvalidDocumentId
|
||||
}
|
||||
UserError::NoPrimaryKeyCandidateFound => Code::NoPrimaryKeyCandidateFound,
|
||||
UserError::NoPrimaryKeyCandidateFound => Code::IndexPrimaryKeyNoCandidateFound,
|
||||
UserError::MultiplePrimaryKeyCandidatesFound { .. } => {
|
||||
Code::MultiplePrimaryKeyCandidatesFound
|
||||
Code::IndexPrimaryKeyMultipleCandidatesFound
|
||||
}
|
||||
UserError::PrimaryKeyCannotBeChanged(_) => Code::PrimaryKeyAlreadyPresent,
|
||||
UserError::PrimaryKeyCannotBeChanged(_) => Code::IndexPrimaryKeyAlreadyExists,
|
||||
UserError::SortRankingRuleMissing => Code::InvalidSearchSort,
|
||||
UserError::InvalidFacetsDistribution { .. } => Code::BadRequest,
|
||||
UserError::InvalidSortableAttribute { .. } => Code::InvalidSearchSort,
|
||||
UserError::CriterionError(_) => Code::InvalidSettingsRankingRules,
|
||||
UserError::CriterionError(_) => Code::InvalidRankingRule,
|
||||
UserError::InvalidGeoField { .. } => Code::InvalidDocumentGeoField,
|
||||
UserError::SortError(_) => Code::InvalidSearchSort,
|
||||
UserError::InvalidMinTypoWordLenSetting(_, _) => {
|
||||
@ -639,7 +369,7 @@ impl ErrorCode for HeedError {
|
||||
fn error_code(&self) -> Code {
|
||||
match self {
|
||||
HeedError::Mdb(MdbError::MapFull) => Code::DatabaseSizeLimitReached,
|
||||
HeedError::Mdb(MdbError::Invalid) => Code::InvalidStore,
|
||||
HeedError::Mdb(MdbError::Invalid) => Code::InvalidStoreFile,
|
||||
HeedError::Io(e) => e.error_code(),
|
||||
HeedError::Mdb(_)
|
||||
| HeedError::Encoding
|
||||
|
Loading…
Reference in New Issue
Block a user