aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaweł Chmielowski <pchmielowski@process-one.net>2016-06-21 12:25:29 +0200
committerPaweł Chmielowski <pchmielowski@process-one.net>2016-06-21 12:25:29 +0200
commit4b9613e8fee3b5be275ff85500d44e982f8a254b (patch)
treeb0bfeb5b45b11e1ed71819e5cc8712682aa83fb9 /src
parentAvoid cleanup on bag when disc_only, switch in memory (#1161) (diff)
Allow {mod_}opt_type to transform values passed to it, and for better error reporting
Diffstat (limited to 'src')
-rw-r--r--src/ejabberd_config.erl53
-rw-r--r--src/gen_mod.erl19
2 files changed, 48 insertions, 24 deletions
diff --git a/src/ejabberd_config.erl b/src/ejabberd_config.erl
index 8c17e577f..139047d9c 100644
--- a/src/ejabberd_config.erl
+++ b/src/ejabberd_config.erl
@@ -770,22 +770,32 @@ add_option(Opt, Val) ->
-spec prepare_opt_val(any(), any(), check_fun(), any()) -> any().
prepare_opt_val(Opt, Val, F, Default) ->
- Res = case F of
- {Mod, Fun} ->
- catch Mod:Fun(Val);
- _ ->
- catch F(Val)
- end,
- case Res of
- {'EXIT', _} ->
+ Call = case F of
+ {Mod, Fun} ->
+ fun() -> Mod:Fun(Val) end;
+ _ ->
+ fun() -> F(Val) end
+ end,
+ try Call() of
+ Res ->
+ Res
+ catch {replace_with, NewRes} ->
+ NewRes;
+ {invalid_syntax, Error} ->
+ ?WARNING_MSG("incorrect value '~s' of option '~s', "
+ "using '~s' as fallback: ~s",
+ [format_term(Val),
+ format_term(Opt),
+ format_term(Default),
+ Error]),
+ Default;
+ _:_ ->
?WARNING_MSG("incorrect value '~s' of option '~s', "
"using '~s' as fallback",
[format_term(Val),
format_term(Opt),
format_term(Default)]),
- Default;
- _ ->
- Res
+ Default
end.
-type check_fun() :: fun((any()) -> any()) | {module(), atom()}.
@@ -908,19 +918,26 @@ get_modules_with_options() ->
validate_opts(#state{opts = Opts} = State) ->
ModOpts = get_modules_with_options(),
- NewOpts = lists:filter(
- fun(#local_config{key = {Opt, _Host}, value = Val}) ->
+ NewOpts = lists:filtermap(
+ fun(#local_config{key = {Opt, _Host}, value = Val} = In) ->
case dict:find(Opt, ModOpts) of
{ok, [Mod|_]} ->
VFun = Mod:opt_type(Opt),
- case catch VFun(Val) of
- {'EXIT', _} ->
+ try VFun(Val) of
+ _ ->
+ true
+ catch {replace_with, NewVal} ->
+ {true, In#local_config{value = NewVal}};
+ {invalid_syntax, Error} ->
+ ?ERROR_MSG("ignoring option '~s' with "
+ "invalid value: ~p: ~s",
+ [Opt, Val, Error]),
+ false;
+ _:_ ->
?ERROR_MSG("ignoring option '~s' with "
"invalid value: ~p",
[Opt, Val]),
- false;
- _ ->
- true
+ false
end;
_ ->
?ERROR_MSG("unknown option '~s' will be likely"
diff --git a/src/gen_mod.erl b/src/gen_mod.erl
index f96397192..1cc65ac21 100644
--- a/src/gen_mod.erl
+++ b/src/gen_mod.erl
@@ -266,18 +266,25 @@ get_opt_host(Host, Opts, Default) ->
ejabberd_regexp:greplace(Val, <<"@HOST@">>, Host).
validate_opts(Module, Opts) ->
- lists:filter(
+ lists:filtermap(
fun({Opt, Val}) ->
case catch Module:mod_opt_type(Opt) of
VFun when is_function(VFun) ->
- case catch VFun(Val) of
- {'EXIT', _} ->
+ try VFun(Val) of
+ _ ->
+ true
+ catch {replace_with, NewVal} ->
+ {true, {Opt, NewVal}};
+ {invalid_syntax, Error} ->
+ ?ERROR_MSG("ignoring invalid value '~p' for "
+ "option '~s' of module '~s': ~s",
+ [Val, Opt, Module, Error]),
+ false;
+ _:_ ->
?ERROR_MSG("ignoring invalid value '~p' for "
"option '~s' of module '~s'",
[Val, Opt, Module]),
- false;
- _ ->
- true
+ false
end;
L when is_list(L) ->
SOpts = str:join([[$', atom_to_list(A), $'] || A <- L], <<", ">>),