Просмотр исходного кода

refactor(emqx_utils): report module function in exception

zmstone 1 год назад
Родитель
Сommit
5365d59ce3

+ 5 - 8
apps/emqx_auth/src/emqx_authn/emqx_authn_schema.erl

@@ -137,19 +137,16 @@ select_union_member(_Kind, Value, _Mods) ->
     throw(#{reason => "not_a_struct", value => Value}).
 
 mod_select_union_member(Kind, Value, Mod) ->
-    emqx_utils:call_first_defined([
-        {Mod, select_union_member, [Kind, Value]},
-        {Mod, select_union_member, [Value]}
-    ]).
+    Args1 = [Kind, Value],
+    Args2 = [Value],
+    ArgsL = [Args1, Args2],
+    emqx_utils:call_first_defined(Mod, select_union_member, ArgsL).
 
 config_refs(Kind, Mods) ->
     lists:append([mod_refs(Kind, Mod) || Mod <- Mods]).
 
 mod_refs(Kind, Mod) ->
-    emqx_utils:call_first_defined([
-        {Mod, refs, [Kind]},
-        {Mod, refs, []}
-    ]).
+    emqx_utils:call_first_defined(Mod, refs, [[Kind], []]).
 
 root_type() ->
     hoconsc:array(authenticator_type()).

+ 13 - 16
apps/emqx_utils/src/emqx_utils.erl

@@ -68,7 +68,7 @@
     format/1,
     format/2,
     format_mfal/2,
-    call_first_defined/1,
+    call_first_defined/3,
     ntoa/1,
     foldl_while/3,
     is_restricted_str/1
@@ -599,21 +599,18 @@ format_mfal(Data, #{with_mfa := true}) ->
 format_mfal(_, _) ->
     undefined.
 
--spec call_first_defined(list({module(), atom(), list()})) -> term() | no_return().
-call_first_defined([{Module, Function, Args} | Rest]) ->
-    try
-        apply(Module, Function, Args)
-    catch
-        error:undef:Stacktrace ->
-            case Stacktrace of
-                [{Module, Function, _, _} | _] ->
-                    call_first_defined(Rest);
-                _ ->
-                    erlang:raise(error, undef, Stacktrace)
-            end
-    end;
-call_first_defined([]) ->
-    error(none_fun_is_defined).
+-spec call_first_defined(module(), atom(), list()) -> term() | no_return().
+call_first_defined(Module, Function, []) ->
+    error({not_exported, Module, Function});
+call_first_defined(Module, Function, [Args | Rest]) ->
+    %% ensure module is loaded
+    _ = apply(Module, module_info, []),
+    case erlang:function_exported(Module, Function, length(Args)) of
+        true ->
+            apply(Module, Function, Args);
+        false ->
+            call_first_defined(Module, Function, Rest)
+    end.
 
 %%------------------------------------------------------------------------------
 %% Internal Functions

+ 2 - 0
apps/emqx_utils/src/emqx_variform.erl

@@ -254,6 +254,7 @@ resolve_func_name(FuncNameStr) ->
                     error:badarg ->
                         throw(#{
                             reason => unknown_variform_function,
+                            module => Mod,
                             function => Fun0
                         })
                 end,
@@ -266,6 +267,7 @@ resolve_func_name(FuncNameStr) ->
                     error:badarg ->
                         throw(#{
                             reason => unknown_variform_function,
+                            module => ?BIF_MOD,
                             function => Fun
                         })
                 end,