diff --git a/apps/emqx_rule_engine/src/emqx_rule_engine_api.erl b/apps/emqx_rule_engine/src/emqx_rule_engine_api.erl index 95c028a1e..15bec4390 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_engine_api.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_engine_api.erl @@ -423,7 +423,12 @@ param_path_id() -> %% Internal functions %%------------------------------------------------------------------------------ -err_msg(Msg) -> emqx_misc:readable_error_msg(Msg). +err_msg({RuleError, {_E, R, _S}}) when is_tuple(R) -> + emqx_misc:readable_error_msg(emqx_json:encode([{RuleError, element(1, R)}])); +err_msg({RuleError, {_E, R, _S}}) -> + emqx_misc:readable_error_msg(emqx_json:encode([{RuleError, R}])); +err_msg(Msg) -> + emqx_misc:readable_error_msg(Msg). format_rule_resp(Rules) when is_list(Rules) -> [format_rule_resp(R) || R <- Rules]; diff --git a/apps/emqx_rule_engine/test/emqx_rule_engine_api_SUITE.erl b/apps/emqx_rule_engine/test/emqx_rule_engine_api_SUITE.erl index 82a305009..3da8ae9db 100644 --- a/apps/emqx_rule_engine/test/emqx_rule_engine_api_SUITE.erl +++ b/apps/emqx_rule_engine/test/emqx_rule_engine_api_SUITE.erl @@ -119,12 +119,31 @@ t_crud_rule_api(_Config) -> emqx_rule_engine_api:'/rules/:id'(get, #{bindings => #{id => RuleID}}) ), + {400, #{ + code := 'BAD_REQUEST', + message := SelectAndTransformJsonError + }} = + emqx_rule_engine_api:'/rule_test'( + post, + test_rule_params(<<"SELECT\n payload.msg\nFROM\n \"t/#\"">>, <<"{\"msg\": \"hel">>) + ), ?assertMatch( - {400, #{ - code := 'BAD_REQUEST', - message := <<"{select_and_transform_error,{error,{decode_json_failed,", _/binary>> - }}, - emqx_rule_engine_api:'/rule_test'(post, test_rule_params()) + #{<<"select_and_transform_error">> := <<"decode_json_failed">>}, + emqx_json:decode(SelectAndTransformJsonError, [return_maps]) + ), + {400, #{ + code := 'BAD_REQUEST', + message := SelectAndTransformBadArgError + }} = + emqx_rule_engine_api:'/rule_test'( + post, + test_rule_params( + <<"SELECT\n payload.msg > 1\nFROM\n \"t/#\"">>, <<"{\"msg\": \"hello\"}">> + ) + ), + ?assertMatch( + #{<<"select_and_transform_error">> := <<"badarg">>}, + emqx_json:decode(SelectAndTransformBadArgError, [return_maps]) ), ok. @@ -221,19 +240,18 @@ t_reset_metrics_on_disable(_Config) -> ?assertMatch(#{passed := 0, matched := 0}, Metrics1), ok. -test_rule_params() -> +test_rule_params(Sql, Payload) -> #{ body => #{ <<"context">> => #{ <<"clientid">> => <<"c_emqx">>, <<"event_type">> => <<"message_publish">>, - <<"payload">> => <<"{\"msg\": \"hel">>, + <<"payload">> => Payload, <<"qos">> => 1, <<"topic">> => <<"t/a">>, <<"username">> => <<"u_emqx">> }, - <<"sql">> => - <<"SELECT\n payload.msg\nFROM\n \"t/#\"">> + <<"sql">> => Sql } }. diff --git a/changes/ce/feat-10059.en.md b/changes/ce/feat-10059.en.md new file mode 100644 index 000000000..2c4de015c --- /dev/null +++ b/changes/ce/feat-10059.en.md @@ -0,0 +1 @@ +Errors returned by rule engine API are formatted in a more human readable way rather than dumping the raw error including the stacktrace. diff --git a/changes/ce/feat-10059.zh.md b/changes/ce/feat-10059.zh.md new file mode 100644 index 000000000..112b943ac --- /dev/null +++ b/changes/ce/feat-10059.zh.md @@ -0,0 +1 @@ +由规则引擎 API 返回的错误以更人性化的方式格式化,而不是转储包括堆栈跟踪的原始错误。