fix(schema): avoid `function_clause` error when compacting errors
Fixes https://emqx.atlassian.net/browse/EMQX-10168 The bridge probe API displayed the typecheck errors for the new timeout duration types correctly, but when an user tried to create the bridge anyway a `function_clause` error was raised when trying to compact hocon errors: ``` 09:47:19.045 [warning] [exception: :error, path: '/bridges', reason: {:case_clause, {:error, {:config_update_crashed, :function_clause}}}, stacktrace: [{:emqx_bridge_api, :create_or_update_bridge, 4, [file: '/home/thales/dev/emqx/emqx/apps/emqx_bridge/src/emqx_bridge_api.erl', line: 602]}, {:minirest_handler, :apply_callback, 3, [file: '/home/thales/dev/emqx/emqx/deps/minirest/src/minirest_handler.erl', line: 111]}, {:minirest_handler, :handle, 2, [file: '/home/thales/dev/emqx/emqx/deps/minirest/src/minirest_handler.erl', line: 44]}, {:minirest_handler, :init, 2, [file: '/home/thales/dev/emqx/emqx/deps/minirest/src/minirest_handler.erl', line: 27]}, {:cowboy_handler, :execute, 2, [file: '/home/thales/dev/emqx/emqx/deps/cowboy/src/cowboy_handler.erl', line: 41]}, {:cowboy_stream_h, :execute, 3, [file: '/home/thales/dev/emqx/emqx/deps/cowboy/src/cowboy_stream_h.erl', line: 318]}, {:cowboy_stream_h, :request_process, 3, [file: '/home/thales/dev/emqx/emqx/deps/cowboy/src/cowboy_stream_h.erl', line: 302]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 240]}]] ``` This fixes the issue so that both APIs return more friendly error messages.
This commit is contained in:
parent
f9ff1007a0
commit
cc8631223e
|
@ -100,7 +100,16 @@ no_stacktrace(Map) ->
|
|||
%% it's maybe too much when reporting to the user
|
||||
-spec compact_errors(any(), Stacktrace :: list()) -> {error, any()}.
|
||||
compact_errors({SchemaModule, Errors}, Stacktrace) ->
|
||||
compact_errors(SchemaModule, Errors, Stacktrace).
|
||||
compact_errors(SchemaModule, Errors, Stacktrace);
|
||||
compact_errors(ErrorContext0, _Stacktrace) when is_map(ErrorContext0) ->
|
||||
case ErrorContext0 of
|
||||
#{exception := #{schema_module := _Mod, message := _Msg} = Detail} ->
|
||||
Error0 = maps:remove(exception, ErrorContext0),
|
||||
Error = maps:merge(Error0, Detail),
|
||||
{error, Error};
|
||||
_ ->
|
||||
{error, ErrorContext0}
|
||||
end.
|
||||
|
||||
compact_errors(SchemaModule, [Error0 | More], _Stacktrace) when is_map(Error0) ->
|
||||
Error1 =
|
||||
|
|
|
@ -2695,7 +2695,11 @@ do_to_timeout_duration(Str, Fn, Max, Unit) ->
|
|||
Msg = lists:flatten(
|
||||
io_lib:format("timeout value too large (max: ~b ~s)", [Max, Unit])
|
||||
),
|
||||
throw(Msg)
|
||||
throw(#{
|
||||
schema_module => ?MODULE,
|
||||
message => Msg,
|
||||
kind => validation_error
|
||||
})
|
||||
end;
|
||||
Err ->
|
||||
Err
|
||||
|
|
|
@ -886,15 +886,27 @@ timeout_types_test_() ->
|
|||
typerefl:from_string(emqx_schema:timeout_duration_s(), <<"4294967000ms">>)
|
||||
),
|
||||
?_assertThrow(
|
||||
"timeout value too large (max: 4294967295 ms)",
|
||||
#{
|
||||
kind := validation_error,
|
||||
message := "timeout value too large (max: 4294967295 ms)",
|
||||
schema_module := emqx_schema
|
||||
},
|
||||
typerefl:from_string(emqx_schema:timeout_duration(), <<"4294967296ms">>)
|
||||
),
|
||||
?_assertThrow(
|
||||
"timeout value too large (max: 4294967295 ms)",
|
||||
#{
|
||||
kind := validation_error,
|
||||
message := "timeout value too large (max: 4294967295 ms)",
|
||||
schema_module := emqx_schema
|
||||
},
|
||||
typerefl:from_string(emqx_schema:timeout_duration_ms(), <<"4294967296ms">>)
|
||||
),
|
||||
?_assertThrow(
|
||||
"timeout value too large (max: 4294967 s)",
|
||||
#{
|
||||
kind := validation_error,
|
||||
message := "timeout value too large (max: 4294967 s)",
|
||||
schema_module := emqx_schema
|
||||
},
|
||||
typerefl:from_string(emqx_schema:timeout_duration_s(), <<"4294967001ms">>)
|
||||
)
|
||||
].
|
||||
|
|
|
@ -67,7 +67,7 @@ health_check_interval_validator_test_() ->
|
|||
parse_and_check_webhook_bridge(webhook_bridge_health_check_hocon(<<"3_600_000ms">>))
|
||||
)},
|
||||
?_assertThrow(
|
||||
#{exception := "timeout value too large" ++ _},
|
||||
#{exception := #{message := "timeout value too large" ++ _}},
|
||||
parse_and_check_webhook_bridge(
|
||||
webhook_bridge_health_check_hocon(<<"150000000000000s">>)
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue