From 8ec14bb07eb4481225096d4cb14b183d0f41673c Mon Sep 17 00:00:00 2001 From: Paulo Zulato Date: Mon, 24 Jul 2023 16:00:34 -0300 Subject: [PATCH] fix(topic_rewrite): handle error when target contains wildcards Fixes https://emqx.atlassian.net/browse/EMQX-10565 --- apps/emqx_modules/src/emqx_rewrite_api.erl | 28 +++++++++++++++++-- .../test/emqx_rewrite_api_SUITE.erl | 2 +- changes/ce/fix-11337.en.md | 1 + rel/i18n/emqx_rewrite_api.hocon | 5 ++++ 4 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 changes/ce/fix-11337.en.md diff --git a/apps/emqx_modules/src/emqx_rewrite_api.erl b/apps/emqx_modules/src/emqx_rewrite_api.erl index cf22daec6..4cf65da8e 100644 --- a/apps/emqx_modules/src/emqx_rewrite_api.erl +++ b/apps/emqx_modules/src/emqx_rewrite_api.erl @@ -28,6 +28,7 @@ -define(MAX_RULES_LIMIT, 20). -define(EXCEED_LIMIT, 'EXCEED_LIMIT'). +-define(BAD_REQUEST, 'BAD_REQUEST'). api_spec() -> emqx_dashboard_swagger:spec(?MODULE). @@ -62,6 +63,10 @@ schema("/mqtt/topic_rewrite") -> hoconsc:array(hoconsc:ref(emqx_modules_schema, "rewrite")), #{desc => ?DESC(update_topic_rewrite_api)} ), + 400 => emqx_dashboard_swagger:error_codes( + [?BAD_REQUEST], + ?DESC(update_topic_rewrite_api_response400) + ), 413 => emqx_dashboard_swagger:error_codes( [?EXCEED_LIMIT], ?DESC(update_topic_rewrite_api_response413) @@ -75,11 +80,30 @@ topic_rewrite(get, _Params) -> topic_rewrite(put, #{body := Body}) -> case length(Body) < ?MAX_RULES_LIMIT of true -> - ok = emqx_rewrite:update(Body), - {200, emqx_rewrite:list()}; + try + ok = emqx_rewrite:update(Body), + {200, emqx_rewrite:list()} + catch + throw:#{ + kind := validation_error, + reason := #{ + msg := "cannot_use_wildcard_for_destination_topic", + invalid_topics := InvalidTopics + } + } -> + Message = get_invalid_wildcard_topic_msg(InvalidTopics), + {400, #{code => ?BAD_REQUEST, message => Message}} + end; _ -> Message = iolist_to_binary( io_lib:format("Max rewrite rules count is ~p", [?MAX_RULES_LIMIT]) ), {413, #{code => ?EXCEED_LIMIT, message => Message}} end. + +get_invalid_wildcard_topic_msg(InvalidTopics) -> + iolist_to_binary( + io_lib:format("Cannot use wildcard for destination topic. Invalid topics: ~p", [ + InvalidTopics + ]) + ). diff --git a/apps/emqx_modules/test/emqx_rewrite_api_SUITE.erl b/apps/emqx_modules/test/emqx_rewrite_api_SUITE.erl index 6c65d351b..96d590b5c 100644 --- a/apps/emqx_modules/test/emqx_rewrite_api_SUITE.erl +++ b/apps/emqx_modules/test/emqx_rewrite_api_SUITE.erl @@ -130,7 +130,7 @@ t_mqtt_topic_rewrite_wildcard(_) -> lists:foreach( fun(Rule) -> ?assertMatch( - {ok, 500, _}, + {ok, 400, _}, request( put, uri(["mqtt", "topic_rewrite"]), diff --git a/changes/ce/fix-11337.en.md b/changes/ce/fix-11337.en.md new file mode 100644 index 000000000..c695cb87f --- /dev/null +++ b/changes/ce/fix-11337.en.md @@ -0,0 +1 @@ +Fix HTTP API error when a publish topic rewrite rule targets a topic with wildcards. Now it returns error 400 (Bad Match) instead of error 500 (Internal Error). diff --git a/rel/i18n/emqx_rewrite_api.hocon b/rel/i18n/emqx_rewrite_api.hocon index 1b56cf24d..58b7af0cd 100644 --- a/rel/i18n/emqx_rewrite_api.hocon +++ b/rel/i18n/emqx_rewrite_api.hocon @@ -15,4 +15,9 @@ update_topic_rewrite_api_response413.desc: update_topic_rewrite_api_response413.label: """Rules count exceed limit""" +update_topic_rewrite_api_response400.desc: +"""Bad request""" +update_topic_rewrite_api_response400.label: +"""Bad request""" + }