Improve handling of errors in tree_action/3

This commit is contained in:
Evgeny Khramtsov 2019-07-29 22:24:26 +03:00
parent 2cd930b7d5
commit d64951c2b2
1 changed files with 33 additions and 14 deletions

View File

@ -3724,26 +3724,45 @@ tree_call(Host, Function, Args) ->
tree_action(Host, Function, Args) -> tree_action(Host, Function, Args) ->
?DEBUG("Tree_action ~p ~p ~p", [Host, Function, Args]), ?DEBUG("Tree_action ~p ~p ~p", [Host, Function, Args]),
ServerHost = serverhost(Host), ServerHost = serverhost(Host),
Fun = fun () -> tree_call(Host, Function, Args) end, DBType = mod_pubsub_opt:db_type(ServerHost),
Ret = case mod_pubsub_opt:db_type(ServerHost) of Fun = fun () ->
try tree_call(Host, Function, Args)
catch ?EX_RULE(Class, Reason, St) when DBType == sql ->
StackTrace = ?EX_STACK(St),
ejabberd_sql:abort({exception, Class, Reason, StackTrace})
end
end,
Ret = case DBType of
mnesia -> mnesia ->
mnesia:sync_dirty(Fun); mnesia:sync_dirty(Fun);
sql -> sql ->
ejabberd_sql:sql_bloc(ServerHost, Fun); ejabberd_sql:sql_bloc(ServerHost, Fun);
_ -> _ ->
Fun() Fun()
end, end,
case Ret of get_tree_action_result(Ret).
{atomic, Result} ->
Result; -spec get_tree_action_result(any()) -> {error, stanza_error() | {virtual, nodeIdx()}} | any().
{aborted, Reason} -> get_tree_action_result({atomic, Result}) ->
?ERROR_MSG("Transaction aborted: ~p~n", [Reason]), Result;
ErrTxt = ?T("Database failure"), get_tree_action_result({aborted, {exception, Class, Reason, StackTrace}}) ->
Lang = ejabberd_option:language(), ?ERROR_MSG("Transaction aborted:~n** ~s",
{error, xmpp:err_internal_server_error(ErrTxt, Lang)}; [misc:format_exception(2, Class, Reason, StackTrace)]),
Other -> get_tree_action_result({error, db_failure});
Other get_tree_action_result({aborted, Reason}) ->
end. ?ERROR_MSG("Transaction aborted: ~p~n", [Reason]),
get_tree_action_result({error, db_failure});
get_tree_action_result({error, #stanza_error{}} = Err) ->
Err;
get_tree_action_result({error, {virtual, _}} = Err) ->
Err;
get_tree_action_result({error, _}) ->
ErrTxt = ?T("Database failure"),
Lang = ejabberd_option:language(),
{error, xmpp:err_internal_server_error(ErrTxt, Lang)};
get_tree_action_result(Other) ->
%% This is very risky, but tree plugins design is really bad
Other.
%% @doc <p>node plugin call.</p> %% @doc <p>node plugin call.</p>
-spec node_call(host(), binary(), atom(), list()) -> {result, any()} | {error, stanza_error()}. -spec node_call(host(), binary(), atom(), list()) -> {result, any()} | {error, stanza_error()}.