Improve invalid uuid error message

This commit is contained in:
Mubelotix
2025-08-04 16:38:00 +02:00
parent 1754745c42
commit 3b0f576d56
3 changed files with 53 additions and 6 deletions

View File

@ -424,6 +424,7 @@ InvalidWebhooks , InvalidRequest , BAD_REQU
InvalidWebhooksUrl , InvalidRequest , BAD_REQUEST ; InvalidWebhooksUrl , InvalidRequest , BAD_REQUEST ;
InvalidWebhooksHeaders , InvalidRequest , BAD_REQUEST ; InvalidWebhooksHeaders , InvalidRequest , BAD_REQUEST ;
ReservedWebhook , InvalidRequest , BAD_REQUEST ; ReservedWebhook , InvalidRequest , BAD_REQUEST ;
InvalidWebhookUuid , InvalidRequest , BAD_REQUEST ;
WebhookNotFound , InvalidRequest , NOT_FOUND WebhookNotFound , InvalidRequest , NOT_FOUND
} }

View File

@ -1,4 +1,5 @@
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::str::FromStr;
use actix_http::header::{ use actix_http::header::{
HeaderName, HeaderValue, InvalidHeaderName as ActixInvalidHeaderName, HeaderName, HeaderValue, InvalidHeaderName as ActixInvalidHeaderName,
@ -195,6 +196,8 @@ enum WebhooksError {
InvalidHeaderValue(String, ActixInvalidHeaderValue), InvalidHeaderValue(String, ActixInvalidHeaderValue),
#[error("Invalid URL `{0}`: {1}")] #[error("Invalid URL `{0}`: {1}")]
InvalidUrl(String, url::ParseError), InvalidUrl(String, url::ParseError),
#[error("Invalid UUID: {0}")]
InvalidUuid(uuid::Error),
} }
impl ErrorCode for WebhooksError { impl ErrorCode for WebhooksError {
@ -208,6 +211,7 @@ impl ErrorCode for WebhooksError {
InvalidHeaderName(_, _) => meilisearch_types::error::Code::InvalidWebhooksHeaders, InvalidHeaderName(_, _) => meilisearch_types::error::Code::InvalidWebhooksHeaders,
InvalidHeaderValue(_, _) => meilisearch_types::error::Code::InvalidWebhooksHeaders, InvalidHeaderValue(_, _) => meilisearch_types::error::Code::InvalidWebhooksHeaders,
InvalidUrl(_, _) => meilisearch_types::error::Code::InvalidWebhooksUrl, InvalidUrl(_, _) => meilisearch_types::error::Code::InvalidWebhooksUrl,
InvalidUuid(_) => meilisearch_types::error::Code::InvalidWebhookUuid,
} }
} }
} }
@ -302,9 +306,9 @@ fn check_changed(uuid: Uuid, webhook: &Webhook) -> Result<(), WebhooksError> {
)] )]
async fn get_webhook( async fn get_webhook(
index_scheduler: GuardedData<ActionPolicy<{ actions::WEBHOOKS_GET }>, Data<IndexScheduler>>, index_scheduler: GuardedData<ActionPolicy<{ actions::WEBHOOKS_GET }>, Data<IndexScheduler>>,
uuid: Path<Uuid>, uuid: Path<String>,
) -> Result<HttpResponse, ResponseError> { ) -> Result<HttpResponse, ResponseError> {
let uuid = uuid.into_inner(); let uuid = Uuid::from_str(&uuid.into_inner()).map_err(InvalidUuid)?;
let mut webhooks = index_scheduler.webhooks(); let mut webhooks = index_scheduler.webhooks();
let webhook = webhooks.webhooks.remove(&uuid).ok_or(WebhookNotFound(uuid))?; let webhook = webhooks.webhooks.remove(&uuid).ok_or(WebhookNotFound(uuid))?;
@ -396,12 +400,12 @@ async fn post_webhook(
)] )]
async fn patch_webhook( async fn patch_webhook(
index_scheduler: GuardedData<ActionPolicy<{ actions::WEBHOOKS_UPDATE }>, Data<IndexScheduler>>, index_scheduler: GuardedData<ActionPolicy<{ actions::WEBHOOKS_UPDATE }>, Data<IndexScheduler>>,
uuid: Path<Uuid>, uuid: Path<String>,
webhook_settings: AwebJson<WebhookSettings, DeserrJsonError>, webhook_settings: AwebJson<WebhookSettings, DeserrJsonError>,
req: HttpRequest, req: HttpRequest,
analytics: Data<Analytics>, analytics: Data<Analytics>,
) -> Result<HttpResponse, ResponseError> { ) -> Result<HttpResponse, ResponseError> {
let uuid = uuid.into_inner(); let uuid = Uuid::from_str(&uuid.into_inner()).map_err(InvalidUuid)?;
let webhook_settings = webhook_settings.into_inner(); let webhook_settings = webhook_settings.into_inner();
debug!(parameters = ?(uuid, &webhook_settings), "Patch webhook"); debug!(parameters = ?(uuid, &webhook_settings), "Patch webhook");
@ -436,11 +440,11 @@ async fn patch_webhook(
)] )]
async fn delete_webhook( async fn delete_webhook(
index_scheduler: GuardedData<ActionPolicy<{ actions::WEBHOOKS_DELETE }>, Data<IndexScheduler>>, index_scheduler: GuardedData<ActionPolicy<{ actions::WEBHOOKS_DELETE }>, Data<IndexScheduler>>,
uuid: Path<Uuid>, uuid: Path<String>,
req: HttpRequest, req: HttpRequest,
analytics: Data<Analytics>, analytics: Data<Analytics>,
) -> Result<HttpResponse, ResponseError> { ) -> Result<HttpResponse, ResponseError> {
let uuid = uuid.into_inner(); let uuid = Uuid::from_str(&uuid.into_inner()).map_err(InvalidUuid)?;
debug!(parameters = ?uuid, "Delete webhook"); debug!(parameters = ?uuid, "Delete webhook");
if uuid.is_nil() { if uuid.is_nil() {

View File

@ -520,3 +520,45 @@ async fn invalid_url_and_headers() {
} }
"#); "#);
} }
#[actix_web::test]
async fn invalid_uuid() {
let server = Server::new().await;
// Test get webhook with invalid UUID
let (value, code) = server.get_webhook("invalid-uuid").await;
snapshot!(code, @"400 Bad Request");
snapshot!(value, @r#"
{
"message": "Invalid UUID: invalid character: expected an optional prefix of `urn:uuid:` followed by [0-9a-fA-F-], found `i` at 1",
"code": "invalid_webhook_uuid",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_webhook_uuid"
}
"#);
// Test update webhook with invalid UUID
let (value, code) =
server.patch_webhook("invalid-uuid", json!({ "url": "https://example.com/hook" })).await;
snapshot!(code, @"400 Bad Request");
snapshot!(value, @r#"
{
"message": "Invalid UUID: invalid character: expected an optional prefix of `urn:uuid:` followed by [0-9a-fA-F-], found `i` at 1",
"code": "invalid_webhook_uuid",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_webhook_uuid"
}
"#);
// Test delete webhook with invalid UUID
let (value, code) = server.delete_webhook("invalid-uuid").await;
snapshot!(code, @"400 Bad Request");
snapshot!(value, @r#"
{
"message": "Invalid UUID: invalid character: expected an optional prefix of `urn:uuid:` followed by [0-9a-fA-F-], found `i` at 1",
"code": "invalid_webhook_uuid",
"type": "invalid_request",
"link": "https://docs.meilisearch.com/errors#invalid_webhook_uuid"
}
"#);
}