diff --git a/src/ejabberd_config.erl b/src/ejabberd_config.erl index bfb4192fd..0c1fad63f 100644 --- a/src/ejabberd_config.erl +++ b/src/ejabberd_config.erl @@ -1542,11 +1542,12 @@ cache_life_time(Host) -> -spec recompile_options() -> ok. recompile_options() -> Exprs = get_exprs(), - try compile_exprs(Exprs) - catch E:R -> + case misc:compile_exprs(ejabberd_options, Exprs) of + ok -> ok; + {error, _} = Err -> ?CRITICAL_MSG("Failed to compile ejabberd_options:~n~s", [string:join(Exprs, io_lib:nl())]), - erlang:raise(E, R, erlang:get_stacktrace()) + erlang:error(Err) end. -spec get_exprs() -> [string()]. @@ -1576,22 +1577,6 @@ get_exprs() -> end, "", Opts) ++ "is_known(_) -> false.", [Module, Export, Knowns|Funs]. --spec compile_exprs([string()]) -> ok. -compile_exprs(Exprs) -> - Forms = lists:map( - fun(Expr) -> - {ok, Tokens, _} = erl_scan:string(lists:flatten(Expr)), - {ok, Form} = erl_parse:parse_form(Tokens), - Form - end, Exprs), - {ok, Code} = case compile:forms(Forms, []) of - {ok, ejabberd_options, Bin} -> {ok, Bin}; - {ok, ejabberd_options, Bin, _Warnings} -> {ok, Bin}; - Error -> Error - end, - {module, _} = code:load_binary(ejabberd_options, "nofile", Code), - ok. - %% @doc This is only for debugging purposes, likely to report a bug -spec dump() -> ok. dump() -> diff --git a/src/misc.erl b/src/misc.erl index ee16882b6..99612b77d 100644 --- a/src/misc.erl +++ b/src/misc.erl @@ -33,7 +33,7 @@ hex_to_bin/1, hex_to_base64/1, expand_keyword/3, atom_to_binary/1, binary_to_atom/1, tuple_to_binary/1, l2i/1, i2l/1, i2l/2, expr_to_term/1, term_to_expr/1, - encode_pid/1, decode_pid/2]). + encode_pid/1, decode_pid/2, compile_exprs/2]). %%%=================================================================== %%% API @@ -213,6 +213,30 @@ decode_pid(PidBin, NodeBin) -> end end. +-spec compile_exprs(module(), [string()]) -> ok | {error, any()}. +compile_exprs(Mod, Exprs) -> + try + Forms = lists:map( + fun(Expr) -> + {ok, Tokens, _} = erl_scan:string(lists:flatten(Expr)), + {ok, Form} = erl_parse:parse_form(Tokens), + Form + end, Exprs), + {ok, Code} = case compile:forms(Forms, []) of + {ok, Mod, Bin} -> {ok, Bin}; + {ok, Mod, Bin, _Warnings} -> {ok, Bin}; + Error -> Error + end, + {module, Mod} = code:load_binary(Mod, "nofile", Code), + ok + catch _:{badmatch, {error, ErrInfo, _ErrLocation}} -> + {error, ErrInfo}; + _:{badmatch, {error, _} = Err} -> + Err; + _:{badmatch, error} -> + {error, compile_failed} + end. + %%%=================================================================== %%% Internal functions %%%===================================================================