]> granicus.if.org Git - ejabberd/commitdiff
Replace more ?ERR_* macros with ?ERRT_*
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>
Tue, 5 Apr 2016 10:09:44 +0000 (13:09 +0300)
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>
Tue, 5 Apr 2016 10:09:44 +0000 (13:09 +0300)
src/mod_announce.erl
src/mod_configure.erl
src/mod_disco.erl
src/mod_irc.erl
src/mod_last.erl
src/mod_muc_room.erl
src/mod_privacy.erl
src/mod_pubsub.erl
src/mod_register.erl
src/node_flat_odbc.erl

index d30cf57f24441235f2d54744696b40ecf9f9dae2..0cf8c53495a56f046618c69f35ec3d86f65236a3 100644 (file)
@@ -211,15 +211,15 @@ disco_identity(Acc, _From, _To, Node, Lang) ->
 
 %%-------------------------------------------------------------------------
 
--define(INFO_RESULT(Allow, Feats),
+-define(INFO_RESULT(Allow, Feats, Lang),
        case Allow of
            deny ->
-               {error, ?ERR_FORBIDDEN};
+               {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
            allow ->
                {result, Feats}
        end).
 
-disco_features(Acc, From, #jid{lserver = LServer} = _To, <<"announce">>, _Lang) ->
+disco_features(Acc, From, #jid{lserver = LServer} = _To, <<"announce">>, Lang) ->
     case gen_mod:is_loaded(LServer, mod_adhoc) of
        false ->
            Acc;
@@ -229,13 +229,14 @@ disco_features(Acc, From, #jid{lserver = LServer} = _To, <<"announce">>, _Lang)
            case {acl:match_rule(LServer, Access1, From),
                  acl:match_rule(global, Access2, From)} of
                {deny, deny} ->
-                   {error, ?ERR_FORBIDDEN};
+                   Txt = <<"Denied by ACL">>,
+                   {error, ?ERRT_FORBIDDEN(Lang, Txt)};
                _ ->
                    {result, []}
            end
     end;
 
-disco_features(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
+disco_features(Acc, From, #jid{lserver = LServer} = _To, Node, Lang) ->
     case gen_mod:is_loaded(LServer, mod_adhoc) of
        false ->
            Acc;
@@ -246,25 +247,25 @@ disco_features(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
            AllowGlobal = acl:match_rule(global, AccessGlobal, From),
            case Node of
                ?NS_ADMIN_ANNOUNCE ->
-                   ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+                   ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
                ?NS_ADMIN_ANNOUNCE_ALL ->
-                   ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+                   ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
                ?NS_ADMIN_SET_MOTD ->
-                   ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+                   ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
                ?NS_ADMIN_EDIT_MOTD ->
-                   ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+                   ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
                ?NS_ADMIN_DELETE_MOTD ->
-                   ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+                   ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
                ?NS_ADMIN_ANNOUNCE_ALLHOSTS ->
-                   ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]);
+                   ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS], Lang);
                ?NS_ADMIN_ANNOUNCE_ALL_ALLHOSTS ->
-                   ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]);
+                   ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS], Lang);
                ?NS_ADMIN_SET_MOTD_ALLHOSTS ->
-                   ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]);
+                   ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS], Lang);
                ?NS_ADMIN_EDIT_MOTD_ALLHOSTS ->
-                   ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]);
+                   ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS], Lang);
                ?NS_ADMIN_DELETE_MOTD_ALLHOSTS ->
-                   ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]);
+                   ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS], Lang);
                _ ->
                    Acc
            end
@@ -283,10 +284,10 @@ disco_features(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
     }
 )).
 
--define(ITEMS_RESULT(Allow, Items),
+-define(ITEMS_RESULT(Allow, Items, Lang),
        case Allow of
            deny ->
-               {error, ?ERR_FORBIDDEN};
+               {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
            allow ->
                {result, Items}
        end).
@@ -320,7 +321,7 @@ disco_items(Acc, From, #jid{lserver = LServer} = To, <<"announce">>, Lang) ->
            announce_items(Acc, From, To, Lang)
     end;
 
-disco_items(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
+disco_items(Acc, From, #jid{lserver = LServer} = _To, Node, Lang) ->
     case gen_mod:is_loaded(LServer, mod_adhoc) of
        false ->
            Acc;
@@ -331,25 +332,25 @@ disco_items(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
            AllowGlobal = acl:match_rule(global, AccessGlobal, From),
            case Node of
                ?NS_ADMIN_ANNOUNCE ->
-                   ?ITEMS_RESULT(Allow, []);
+                   ?ITEMS_RESULT(Allow, [], Lang);
                ?NS_ADMIN_ANNOUNCE_ALL ->
-                   ?ITEMS_RESULT(Allow, []);
+                   ?ITEMS_RESULT(Allow, [], Lang);
                ?NS_ADMIN_SET_MOTD ->
-                   ?ITEMS_RESULT(Allow, []);
+                   ?ITEMS_RESULT(Allow, [], Lang);
                ?NS_ADMIN_EDIT_MOTD ->
-                   ?ITEMS_RESULT(Allow, []);
+                   ?ITEMS_RESULT(Allow, [], Lang);
                ?NS_ADMIN_DELETE_MOTD ->
-                   ?ITEMS_RESULT(Allow, []);
+                   ?ITEMS_RESULT(Allow, [], Lang);
                ?NS_ADMIN_ANNOUNCE_ALLHOSTS ->
-                   ?ITEMS_RESULT(AllowGlobal, []);
+                   ?ITEMS_RESULT(AllowGlobal, [], Lang);
                ?NS_ADMIN_ANNOUNCE_ALL_ALLHOSTS ->
-                   ?ITEMS_RESULT(AllowGlobal, []);
+                   ?ITEMS_RESULT(AllowGlobal, [], Lang);
                ?NS_ADMIN_SET_MOTD_ALLHOSTS ->
-                   ?ITEMS_RESULT(AllowGlobal, []);
+                   ?ITEMS_RESULT(AllowGlobal, [], Lang);
                ?NS_ADMIN_EDIT_MOTD_ALLHOSTS ->
-                   ?ITEMS_RESULT(AllowGlobal, []);
+                   ?ITEMS_RESULT(AllowGlobal, [], Lang);
                ?NS_ADMIN_DELETE_MOTD_ALLHOSTS ->
-                   ?ITEMS_RESULT(AllowGlobal, []);
+                   ?ITEMS_RESULT(AllowGlobal, [], Lang);
                _ ->
                    Acc
            end
@@ -396,7 +397,8 @@ announce_items(Acc, From, #jid{lserver = LServer, server = Server} = _To, Lang)
 commands_result(Allow, From, To, Request) ->
     case Allow of
        deny ->
-           {error, ?ERR_FORBIDDEN};
+           Lang = Request#adhoc_request.lang,
+           {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
        allow ->
            announce_commands(From, To, Request)
     end.
@@ -463,12 +465,13 @@ announce_commands(From, To,
            %% User returns form.
            case jlib:parse_xdata_submit(XData) of
                invalid ->
-                   {error, ?ERR_BAD_REQUEST};
+                   {error, ?ERRT_BAD_REQUEST(Lang, <<"Incorrect data form">>)};
                Fields ->
                    handle_adhoc_form(From, To, Request, Fields)
            end;
        true ->
-           {error, ?ERR_BAD_REQUEST}
+           Txt = <<"Incorrect action or data form">>,
+           {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
     end.
 
 -define(VVALUE(Val),
@@ -688,7 +691,9 @@ announce_all(From, To, Packet) ->
     Access = get_access(Host),
     case acl:match_rule(Host, Access, From) of
        deny ->
-           Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
+           Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
+           Txt = <<"Denied by ACL">>,
+           Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
            ejabberd_router:route(To, From, Err);
        allow ->
            Local = jid:make(<<>>, To#jid.server, <<>>),
@@ -703,7 +708,9 @@ announce_all_hosts_all(From, To, Packet) ->
     Access = get_access(global),
     case acl:match_rule(global, Access, From) of
        deny ->
-           Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
+           Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
+           Txt = <<"Denied by ACL">>,
+           Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
            ejabberd_router:route(To, From, Err);
        allow ->
            Local = jid:make(<<>>, To#jid.server, <<>>),
@@ -719,7 +726,9 @@ announce_online(From, To, Packet) ->
     Access = get_access(Host),
     case acl:match_rule(Host, Access, From) of
        deny ->
-           Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
+           Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
+           Txt = <<"Denied by ACL">>,
+           Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
            ejabberd_router:route(To, From, Err);
        allow ->
            announce_online1(ejabberd_sm:get_vh_session_list(Host),
@@ -731,7 +740,9 @@ announce_all_hosts_online(From, To, Packet) ->
     Access = get_access(global),
     case acl:match_rule(global, Access, From) of
        deny ->
-           Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
+           Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
+           Txt = <<"Denied by ACL">>,
+           Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
            ejabberd_router:route(To, From, Err);
        allow ->
            announce_online1(ejabberd_sm:dirty_get_sessions_list(),
@@ -752,7 +763,9 @@ announce_motd(From, To, Packet) ->
     Access = get_access(Host),
     case acl:match_rule(Host, Access, From) of
        deny ->
-           Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
+           Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
+           Txt = <<"Denied by ACL">>,
+           Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
            ejabberd_router:route(To, From, Err);
        allow ->
            announce_motd(Host, Packet)
@@ -762,7 +775,9 @@ announce_all_hosts_motd(From, To, Packet) ->
     Access = get_access(global),
     case acl:match_rule(global, Access, From) of
        deny ->
-           Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
+           Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
+           Txt = <<"Denied by ACL">>,
+           Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
            ejabberd_router:route(To, From, Err);
        allow ->
            Hosts = ?MYHOSTS,
@@ -815,7 +830,9 @@ announce_motd_update(From, To, Packet) ->
     Access = get_access(Host),
     case acl:match_rule(Host, Access, From) of
        deny ->
-           Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
+           Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
+           Txt = <<"Denied by ACL">>,
+           Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
            ejabberd_router:route(To, From, Err);
        allow ->
            announce_motd_update(Host, Packet)
@@ -825,7 +842,9 @@ announce_all_hosts_motd_update(From, To, Packet) ->
     Access = get_access(global),
     case acl:match_rule(global, Access, From) of
        deny ->
-           Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
+           Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
+           Txt = <<"Denied by ACL">>,
+           Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
            ejabberd_router:route(To, From, Err);
        allow ->
            Hosts = ?MYHOSTS,
@@ -861,7 +880,9 @@ announce_motd_delete(From, To, Packet) ->
     Access = get_access(Host),
     case acl:match_rule(Host, Access, From) of
        deny ->
-           Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
+           Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
+           Txt = <<"Denied by ACL">>,
+           Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
            ejabberd_router:route(To, From, Err);
        allow ->
            announce_motd_delete(Host)
@@ -871,7 +892,9 @@ announce_all_hosts_motd_delete(From, To, Packet) ->
     Access = get_access(global),
     case acl:match_rule(global, Access, From) of
        deny ->
-           Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
+           Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
+           Txt = <<"Denied by ACL">>,
+           Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
            ejabberd_router:route(To, From, Err);
        allow ->
            Hosts = ?MYHOSTS,
index 5e011704779219fe7b475f453dca0e345785d6fe..a836c33bdd4d79ddba0230cada6f0b9606b65e35 100644 (file)
@@ -198,81 +198,81 @@ get_local_identity(Acc, _From, _To, Node, Lang) ->
 
 %%%-----------------------------------------------------------------------
 
--define(INFO_RESULT(Allow, Feats),
+-define(INFO_RESULT(Allow, Feats, Lang),
        case Allow of
-         deny -> {error, ?ERR_FORBIDDEN};
+         deny -> {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
          allow -> {result, Feats}
        end).
 
 get_sm_features(Acc, From,
-               #jid{lserver = LServer} = _To, Node, _Lang) ->
+               #jid{lserver = LServer} = _To, Node, Lang) ->
     case gen_mod:is_loaded(LServer, mod_adhoc) of
       false -> Acc;
       _ ->
          Allow = acl:match_rule(LServer, configure, From),
          case Node of
-           <<"config">> -> ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+           <<"config">> -> ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
            _ -> Acc
          end
     end.
 
 get_local_features(Acc, From,
-                  #jid{lserver = LServer} = _To, Node, _Lang) ->
+                  #jid{lserver = LServer} = _To, Node, Lang) ->
     case gen_mod:is_loaded(LServer, mod_adhoc) of
       false -> Acc;
       _ ->
          LNode = tokenize(Node),
          Allow = acl:match_rule(LServer, configure, From),
          case LNode of
-           [<<"config">>] -> ?INFO_RESULT(Allow, []);
-           [<<"user">>] -> ?INFO_RESULT(Allow, []);
-           [<<"online users">>] -> ?INFO_RESULT(Allow, []);
-           [<<"all users">>] -> ?INFO_RESULT(Allow, []);
+           [<<"config">>] -> ?INFO_RESULT(Allow, [], Lang);
+           [<<"user">>] -> ?INFO_RESULT(Allow, [], Lang);
+           [<<"online users">>] -> ?INFO_RESULT(Allow, [], Lang);
+           [<<"all users">>] -> ?INFO_RESULT(Allow, [], Lang);
            [<<"all users">>, <<$@, _/binary>>] ->
-               ?INFO_RESULT(Allow, []);
-           [<<"outgoing s2s">> | _] -> ?INFO_RESULT(Allow, []);
-           [<<"running nodes">>] -> ?INFO_RESULT(Allow, []);
-           [<<"stopped nodes">>] -> ?INFO_RESULT(Allow, []);
+               ?INFO_RESULT(Allow, [], Lang);
+           [<<"outgoing s2s">> | _] -> ?INFO_RESULT(Allow, [], Lang);
+           [<<"running nodes">>] -> ?INFO_RESULT(Allow, [], Lang);
+           [<<"stopped nodes">>] -> ?INFO_RESULT(Allow, [], Lang);
            [<<"running nodes">>, _ENode] ->
-               ?INFO_RESULT(Allow, [?NS_STATS]);
+               ?INFO_RESULT(Allow, [?NS_STATS], Lang);
            [<<"running nodes">>, _ENode, <<"DB">>] ->
-               ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+               ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
            [<<"running nodes">>, _ENode, <<"modules">>] ->
-               ?INFO_RESULT(Allow, []);
+               ?INFO_RESULT(Allow, [], Lang);
            [<<"running nodes">>, _ENode, <<"modules">>, _] ->
-               ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+               ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
            [<<"running nodes">>, _ENode, <<"backup">>] ->
-               ?INFO_RESULT(Allow, []);
+               ?INFO_RESULT(Allow, [], Lang);
            [<<"running nodes">>, _ENode, <<"backup">>, _] ->
-               ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+               ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
            [<<"running nodes">>, _ENode, <<"import">>] ->
-               ?INFO_RESULT(Allow, []);
+               ?INFO_RESULT(Allow, [], Lang);
            [<<"running nodes">>, _ENode, <<"import">>, _] ->
-               ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+               ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
            [<<"running nodes">>, _ENode, <<"restart">>] ->
-               ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+               ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
            [<<"running nodes">>, _ENode, <<"shutdown">>] ->
-               ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+               ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
            [<<"config">>, _] ->
-               ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+               ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
            ?NS_ADMINL(<<"add-user">>) ->
-               ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+               ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
            ?NS_ADMINL(<<"delete-user">>) ->
-               ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+               ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
            ?NS_ADMINL(<<"end-user-session">>) ->
-               ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+               ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
            ?NS_ADMINL(<<"get-user-password">>) ->
-               ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+               ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
            ?NS_ADMINL(<<"change-user-password">>) ->
-               ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+               ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
            ?NS_ADMINL(<<"get-user-lastlogin">>) ->
-               ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+               ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
            ?NS_ADMINL(<<"user-stats">>) ->
-               ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+               ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
            ?NS_ADMINL(<<"get-registered-users-num">>) ->
-               ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+               ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
            ?NS_ADMINL(<<"get-online-users-num">>) ->
-               ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+               ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
            _ -> Acc
          end
     end.
@@ -318,7 +318,8 @@ get_sm_items(Acc, From,
                {result,
                 Items ++ Nodes ++ get_user_resources(User, Server)};
            {allow, <<"config">>} -> {result, []};
-           {_, <<"config">>} -> {error, ?ERR_FORBIDDEN};
+           {_, <<"config">>} ->
+                 {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
            _ -> Acc
          end
     end.
@@ -448,63 +449,64 @@ get_local_items(Acc, From, #jid{lserver = LServer} = To,
       _ ->
          LNode = tokenize(Node),
          Allow = acl:match_rule(LServer, configure, From),
+         Err = ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>),
          case LNode of
            [<<"config">>] ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            [<<"user">>] ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            [<<"online users">>] ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            [<<"all users">>] ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            [<<"all users">>, <<$@, _/binary>>] ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            [<<"outgoing s2s">> | _] ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            [<<"running nodes">>] ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            [<<"stopped nodes">>] ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            [<<"running nodes">>, _ENode] ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            [<<"running nodes">>, _ENode, <<"DB">>] ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            [<<"running nodes">>, _ENode, <<"modules">>] ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            [<<"running nodes">>, _ENode, <<"modules">>, _] ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            [<<"running nodes">>, _ENode, <<"backup">>] ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            [<<"running nodes">>, _ENode, <<"backup">>, _] ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            [<<"running nodes">>, _ENode, <<"import">>] ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            [<<"running nodes">>, _ENode, <<"import">>, _] ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            [<<"running nodes">>, _ENode, <<"restart">>] ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            [<<"running nodes">>, _ENode, <<"shutdown">>] ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            [<<"config">>, _] ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            ?NS_ADMINL(<<"add-user">>) ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            ?NS_ADMINL(<<"delete-user">>) ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            ?NS_ADMINL(<<"end-user-session">>) ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            ?NS_ADMINL(<<"get-user-password">>) ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            ?NS_ADMINL(<<"change-user-password">>) ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            ?NS_ADMINL(<<"get-user-lastlogin">>) ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            ?NS_ADMINL(<<"user-stats">>) ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            ?NS_ADMINL(<<"get-registered-users-num">>) ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            ?NS_ADMINL(<<"get-online-users-num">>) ->
-               ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+               ?ITEMS_RESULT(Allow, LNode, {error, Err});
            _ -> Acc
          end
     end.
@@ -562,33 +564,29 @@ get_local_items({_, Host}, [<<"all users">>], _Server,
 get_local_items({_, Host},
                [<<"all users">>, <<$@, Diap/binary>>], _Server,
                _Lang) ->
-    case catch ejabberd_auth:get_vh_registered_users(Host)
-       of
-      {'EXIT', _Reason} -> ?ERR_INTERNAL_SERVER_ERROR;
-      Users ->
-         SUsers = lists:sort([{S, U} || {U, S} <- Users]),
-         case catch begin
-                      [S1, S2] = ejabberd_regexp:split(Diap, <<"-">>),
-                      N1 = jlib:binary_to_integer(S1),
-                      N2 = jlib:binary_to_integer(S2),
-                      Sub = lists:sublist(SUsers, N1, N2 - N1 + 1),
-                      lists:map(fun ({S, U}) ->
-                                        #xmlel{name = <<"item">>,
-                                               attrs =
-                                                   [{<<"jid">>,
-                                                     <<U/binary, "@",
-                                                       S/binary>>},
-                                                    {<<"name">>,
-                                                     <<U/binary, "@",
-                                                       S/binary>>}],
-                                               children = []}
-                                end,
-                                Sub)
-                    end
-             of
-           {'EXIT', _Reason} -> ?ERR_NOT_ACCEPTABLE;
-           Res -> {result, Res}
-         end
+    Users = ejabberd_auth:get_vh_registered_users(Host),
+    SUsers = lists:sort([{S, U} || {U, S} <- Users]),
+    case catch begin
+                  [S1, S2] = ejabberd_regexp:split(Diap, <<"-">>),
+                  N1 = jlib:binary_to_integer(S1),
+                  N2 = jlib:binary_to_integer(S2),
+                  Sub = lists:sublist(SUsers, N1, N2 - N1 + 1),
+                  lists:map(fun ({S, U}) ->
+                                    #xmlel{name = <<"item">>,
+                                           attrs =
+                                               [{<<"jid">>,
+                                                 <<U/binary, "@",
+                                                   S/binary>>},
+                                                {<<"name">>,
+                                                 <<U/binary, "@",
+                                                   S/binary>>}],
+                                           children = []}
+                            end,
+                            Sub)
+              end
+    of
+       {'EXIT', _Reason} -> ?ERR_NOT_ACCEPTABLE;
+       Res -> {result, Res}
     end;
 get_local_items({_, Host}, [<<"outgoing s2s">>],
                _Server, Lang) ->
@@ -826,33 +824,33 @@ get_stopped_nodes(_Lang) ->
 %%-------------------------------------------------------------------------
 
 -define(COMMANDS_RESULT(LServerOrGlobal, From, To,
-                       Request),
+                       Request, Lang),
        case acl:match_rule(LServerOrGlobal, configure, From) of
-         deny -> {error, ?ERR_FORBIDDEN};
+         deny -> {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
          allow -> adhoc_local_commands(From, To, Request)
        end).
 
 adhoc_local_commands(Acc, From,
                     #jid{lserver = LServer} = To,
-                    #adhoc_request{node = Node} = Request) ->
+                    #adhoc_request{node = Node, lang = Lang} = Request) ->
     LNode = tokenize(Node),
     case LNode of
       [<<"running nodes">>, _ENode, <<"DB">>] ->
-         ?COMMANDS_RESULT(global, From, To, Request);
+         ?COMMANDS_RESULT(global, From, To, Request, Lang);
       [<<"running nodes">>, _ENode, <<"modules">>, _] ->
-         ?COMMANDS_RESULT(LServer, From, To, Request);
+         ?COMMANDS_RESULT(LServer, From, To, Request, Lang);
       [<<"running nodes">>, _ENode, <<"backup">>, _] ->
-         ?COMMANDS_RESULT(global, From, To, Request);
+         ?COMMANDS_RESULT(global, From, To, Request, Lang);
       [<<"running nodes">>, _ENode, <<"import">>, _] ->
-         ?COMMANDS_RESULT(global, From, To, Request);
+         ?COMMANDS_RESULT(global, From, To, Request, Lang);
       [<<"running nodes">>, _ENode, <<"restart">>] ->
-         ?COMMANDS_RESULT(global, From, To, Request);
+         ?COMMANDS_RESULT(global, From, To, Request, Lang);
       [<<"running nodes">>, _ENode, <<"shutdown">>] ->
-         ?COMMANDS_RESULT(global, From, To, Request);
+         ?COMMANDS_RESULT(global, From, To, Request, Lang);
       [<<"config">>, _] ->
-         ?COMMANDS_RESULT(LServer, From, To, Request);
+         ?COMMANDS_RESULT(LServer, From, To, Request, Lang);
       ?NS_ADMINL(_) ->
-         ?COMMANDS_RESULT(LServer, From, To, Request);
+         ?COMMANDS_RESULT(LServer, From, To, Request, Lang);
       _ -> Acc
     end.
 
@@ -882,7 +880,8 @@ adhoc_local_commands(From,
           end;
        XData /= false, ActionIsExecute ->
           case jlib:parse_xdata_submit(XData) of
-            invalid -> {error, ?ERR_BAD_REQUEST};
+            invalid ->
+                {error, ?ERRT_BAD_REQUEST(Lang, <<"Incorrect data form">>)};
             Fields ->
                 case catch set_form(From, LServer, LNode, Lang, Fields)
                     of
@@ -898,7 +897,8 @@ adhoc_local_commands(From,
                   {error, Error} -> {error, Error}
                 end
           end;
-       true -> {error, ?ERR_BAD_REQUEST}
+       true ->
+         {error, ?ERRT_BAD_REQUEST(Lang, <<"Incorrect action or data form">>)}
     end.
 
 -define(TVFIELD(Type, Var, Val),
@@ -980,10 +980,14 @@ adhoc_local_commands(From,
 get_form(_Host, [<<"running nodes">>, ENode, <<"DB">>],
         Lang) ->
     case search_running_node(ENode) of
-      false -> {error, ?ERR_ITEM_NOT_FOUND};
+      false ->
+         Txt = <<"No running node found">>,
+         {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
       Node ->
          case ejabberd_cluster:call(Node, mnesia, system_info, [tables]) of
-           {badrpc, _Reason} ->
+           {badrpc, Reason} ->
+               ?ERROR_MSG("RPC call mnesia:system_info(tables) on node "
+                          "~s failed: ~p", [Node, Reason]),
                {error, ?ERR_INTERNAL_SERVER_ERROR};
            Tables ->
                STables = lists:sort(Tables),
@@ -1023,10 +1027,14 @@ get_form(Host,
         [<<"running nodes">>, ENode, <<"modules">>, <<"stop">>],
         Lang) ->
     case search_running_node(ENode) of
-      false -> {error, ?ERR_ITEM_NOT_FOUND};
+      false ->
+         Txt = <<"No running node found">>,
+         {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
       Node ->
          case ejabberd_cluster:call(Node, gen_mod, loaded_modules, [Host]) of
-           {badrpc, _Reason} ->
+           {badrpc, Reason} ->
+               ?ERROR_MSG("RPC call gen_mod:loaded_modules(~s) on node "
+                          "~s failed: ~p", [Host, Node, Reason]),
                {error, ?ERR_INTERNAL_SERVER_ERROR};
            Modules ->
                SModules = lists:sort(Modules),
@@ -1562,9 +1570,11 @@ get_form(_Host, _, _Lang) ->
     {error, ?ERR_SERVICE_UNAVAILABLE}.
 
 set_form(_From, _Host,
-        [<<"running nodes">>, ENode, <<"DB">>], _Lang, XData) ->
+        [<<"running nodes">>, ENode, <<"DB">>], Lang, XData) ->
     case search_running_node(ENode) of
-      false -> {error, ?ERR_ITEM_NOT_FOUND};
+      false ->
+         Txt = <<"No running node found">>,
+         {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
       Node ->
          lists:foreach(fun ({SVar, SVals}) ->
                                Table = jlib:binary_to_atom(SVar),
@@ -1596,9 +1606,11 @@ set_form(_From, _Host,
     end;
 set_form(_From, Host,
         [<<"running nodes">>, ENode, <<"modules">>, <<"stop">>],
-        _Lang, XData) ->
+        Lang, XData) ->
     case search_running_node(ENode) of
-      false -> {error, ?ERR_ITEM_NOT_FOUND};
+      false ->
+         Txt = <<"No running node found">>,
+         {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
       Node ->
          lists:foreach(fun ({Var, Vals}) ->
                                case Vals of
@@ -1615,12 +1627,16 @@ set_form(_From, Host,
 set_form(_From, Host,
         [<<"running nodes">>, ENode, <<"modules">>,
          <<"start">>],
-        _Lang, XData) ->
+        Lang, XData) ->
     case search_running_node(ENode) of
-      false -> {error, ?ERR_ITEM_NOT_FOUND};
+      false ->
+         Txt = <<"No running node found">>,
+         {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
       Node ->
          case lists:keysearch(<<"modules">>, 1, XData) of
-           false -> {error, ?ERR_BAD_REQUEST};
+           false ->
+               Txt = <<"No 'modules' found in data form">>,
+               {error, ?ERRT_BAD_REQUEST(Lang, Txt)};
            {value, {_, Strings}} ->
                String = lists:foldl(fun (S, Res) ->
                                             <<Res/binary, S/binary, "\n">>
@@ -1637,98 +1653,143 @@ set_form(_From, Host,
                                          end,
                                          Modules),
                            {result, []};
-                       _ -> {error, ?ERR_BAD_REQUEST}
+                       _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Parse failed">>)}
                      end;
-                 _ -> {error, ?ERR_BAD_REQUEST}
+                 _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Scan failed">>)}
                end
          end
     end;
 set_form(_From, _Host,
         [<<"running nodes">>, ENode, <<"backup">>,
          <<"backup">>],
-        _Lang, XData) ->
+        Lang, XData) ->
     case search_running_node(ENode) of
-      false -> {error, ?ERR_ITEM_NOT_FOUND};
+      false ->
+         Txt = <<"No running node found">>,
+         {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
       Node ->
          case lists:keysearch(<<"path">>, 1, XData) of
-           false -> {error, ?ERR_BAD_REQUEST};
+           false ->
+               Txt = <<"No 'path' found in data form">>,
+               {error, ?ERRT_BAD_REQUEST(Lang, Txt)};
            {value, {_, [String]}} ->
                case ejabberd_cluster:call(Node, mnesia, backup, [String]) of
-                 {badrpc, _Reason} ->
+                 {badrpc, Reason} ->
+                     ?ERROR_MSG("RPC call mnesia:backup(~s) to node ~s "
+                                "failed: ~p", [String, Node, Reason]),
+                     {error, ?ERR_INTERNAL_SERVER_ERROR};
+                 {error, Reason} ->
+                     ?ERROR_MSG("RPC call mnesia:backup(~s) to node ~s "
+                                "failed: ~p", [String, Node, Reason]),
                      {error, ?ERR_INTERNAL_SERVER_ERROR};
-                 {error, _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR};
                  _ -> {result, []}
                end;
-           _ -> {error, ?ERR_BAD_REQUEST}
+           _ ->
+               Txt = <<"Incorrect value of 'path' in data form">>,
+               {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
          end
     end;
 set_form(_From, _Host,
         [<<"running nodes">>, ENode, <<"backup">>,
          <<"restore">>],
-        _Lang, XData) ->
+        Lang, XData) ->
     case search_running_node(ENode) of
-      false -> {error, ?ERR_ITEM_NOT_FOUND};
+      false ->
+         Txt = <<"No running node found">>,
+         {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
       Node ->
          case lists:keysearch(<<"path">>, 1, XData) of
-           false -> {error, ?ERR_BAD_REQUEST};
+           false ->
+               Txt = <<"No 'path' found in data form">>,
+               {error, ?ERRT_BAD_REQUEST(Lang, Txt)};
            {value, {_, [String]}} ->
                case ejabberd_cluster:call(Node, ejabberd_admin, restore, [String])
                    of
-                 {badrpc, _Reason} ->
+                 {badrpc, Reason} ->
+                     ?ERROR_MSG("RPC call ejabberd_admin:restore(~s) to node "
+                                "~s failed: ~p", [String, Node, Reason]),
+                     {error, ?ERR_INTERNAL_SERVER_ERROR};
+                 {error, Reason} ->
+                     ?ERROR_MSG("RPC call ejabberd_admin:restore(~s) to node "
+                                "~s failed: ~p", [String, Node, Reason]),
                      {error, ?ERR_INTERNAL_SERVER_ERROR};
-                 {error, _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR};
                  _ -> {result, []}
                end;
-           _ -> {error, ?ERR_BAD_REQUEST}
+           _ ->
+               Txt = <<"Incorrect value of 'path' in data form">>,
+               {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
          end
     end;
 set_form(_From, _Host,
         [<<"running nodes">>, ENode, <<"backup">>,
          <<"textfile">>],
-        _Lang, XData) ->
+        Lang, XData) ->
     case search_running_node(ENode) of
-      false -> {error, ?ERR_ITEM_NOT_FOUND};
+      false ->
+         Txt = <<"No running node found">>,
+         {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
       Node ->
          case lists:keysearch(<<"path">>, 1, XData) of
-           false -> {error, ?ERR_BAD_REQUEST};
+           false ->
+               Txt = <<"No 'path' found in data form">>,
+               {error, ?ERRT_BAD_REQUEST(Lang, Txt)};
            {value, {_, [String]}} ->
                case ejabberd_cluster:call(Node, ejabberd_admin, dump_to_textfile,
                              [String])
                    of
-                 {badrpc, _Reason} ->
+                 {badrpc, Reason} ->
+                     ?ERROR_MSG("RPC call ejabberd_admin:dump_to_textfile(~s) "
+                                "to node ~s failed: ~p", [String, Node, Reason]),
+                     {error, ?ERR_INTERNAL_SERVER_ERROR};
+                 {error, Reason} ->
+                     ?ERROR_MSG("RPC call ejabberd_admin:dump_to_textfile(~s) "
+                                "to node ~s failed: ~p", [String, Node, Reason]),
                      {error, ?ERR_INTERNAL_SERVER_ERROR};
-                 {error, _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR};
                  _ -> {result, []}
                end;
-           _ -> {error, ?ERR_BAD_REQUEST}
+           _ ->
+               Txt = <<"Incorrect value of 'path' in data form">>,
+               {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
          end
     end;
 set_form(_From, _Host,
         [<<"running nodes">>, ENode, <<"import">>, <<"file">>],
-        _Lang, XData) ->
+        Lang, XData) ->
     case search_running_node(ENode) of
-      false -> {error, ?ERR_ITEM_NOT_FOUND};
+      false ->
+         Txt = <<"No running node found">>,
+         {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
       Node ->
          case lists:keysearch(<<"path">>, 1, XData) of
-           false -> {error, ?ERR_BAD_REQUEST};
+           false ->
+               Txt = <<"No 'path' found in data form">>,
+               {error, ?ERRT_BAD_REQUEST(Lang, Txt)};
            {value, {_, [String]}} ->
                ejabberd_cluster:call(Node, jd2ejd, import_file, [String]),
                {result, []};
-           _ -> {error, ?ERR_BAD_REQUEST}
+           _ ->
+               Txt = <<"Incorrect value of 'path' in data form">>,
+               {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
          end
     end;
 set_form(_From, _Host,
         [<<"running nodes">>, ENode, <<"import">>, <<"dir">>],
-        _Lang, XData) ->
+        Lang, XData) ->
     case search_running_node(ENode) of
-      false -> {error, ?ERR_ITEM_NOT_FOUND};
+      false ->
+         Txt = <<"No running node found">>,
+         {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
       Node ->
          case lists:keysearch(<<"path">>, 1, XData) of
-           false -> {error, ?ERR_BAD_REQUEST};
+           false ->
+               Txt = <<"No 'path' found in data form">>,
+               {error, ?ERRT_BAD_REQUEST(Lang, Txt)};
            {value, {_, [String]}} ->
                ejabberd_cluster:call(Node, jd2ejd, import_dir, [String]),
                {result, []};
-           _ -> {error, ?ERR_BAD_REQUEST}
+           _ ->
+               Txt = <<"Incorrect value of 'path' in data form">>,
+               {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
          end
     end;
 set_form(From, Host,
@@ -1739,7 +1800,7 @@ set_form(From, Host,
         [<<"running nodes">>, ENode, <<"shutdown">>], _Lang,
         XData) ->
     stop_node(From, Host, ENode, stop, XData);
-set_form(_From, Host, [<<"config">>, <<"acls">>], _Lang,
+set_form(_From, Host, [<<"config">>, <<"acls">>], Lang,
         XData) ->
     case lists:keysearch(<<"acls">>, 1, XData) of
       {value, {_, Strings}} ->
@@ -1753,14 +1814,16 @@ set_form(_From, Host, [<<"config">>, <<"acls">>], _Lang,
                  {ok, ACLs} ->
                      acl:add_list(Host, ACLs, true),
                       {result, []};
-                 _ -> {error, ?ERR_BAD_REQUEST}
+                 _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Parse failed">>)}
                end;
-           _ -> {error, ?ERR_BAD_REQUEST}
+           _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Scan failed">>)}
          end;
-      _ -> {error, ?ERR_BAD_REQUEST}
+      _ ->
+         Txt = <<"No 'acls' found in data form">>,
+         {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
     end;
 set_form(_From, Host, [<<"config">>, <<"access">>],
-        _Lang, XData) ->
+        Lang, XData) ->
     SetAccess = fun (Rs) ->
                        mnesia:transaction(fun () ->
                                                   Os = mnesia:select(local_config,
@@ -1803,11 +1866,13 @@ set_form(_From, Host, [<<"config">>, <<"access">>],
                        {atomic, _} -> {result, []};
                        _ -> {error, ?ERR_BAD_REQUEST}
                      end;
-                 _ -> {error, ?ERR_BAD_REQUEST}
+                 _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Parse failed">>)}
                end;
-           _ -> {error, ?ERR_BAD_REQUEST}
+           _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Scan failed">>)}
          end;
-      _ -> {error, ?ERR_BAD_REQUEST}
+      _ ->
+         Txt = <<"No 'access' found in data form">>,
+         {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
     end;
 set_form(From, Host, ?NS_ADMINL(<<"add-user">>), _Lang,
         XData) ->
@@ -2052,7 +2117,7 @@ adhoc_sm_commands(_Acc, From,
                                 action = Action, xdata = XData} =
                      Request) ->
     case acl:match_rule(LServer, configure, From) of
-      deny -> {error, ?ERR_FORBIDDEN};
+      deny -> {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
       allow ->
          ActionIsExecute = lists:member(Action,
                                         [<<"">>, <<"execute">>,
@@ -2071,11 +2136,15 @@ adhoc_sm_commands(_Acc, From,
                 end;
             XData /= false, ActionIsExecute ->
                 case jlib:parse_xdata_submit(XData) of
-                  invalid -> {error, ?ERR_BAD_REQUEST};
+                  invalid ->
+                      Txt = <<"Incorrect data form">>,
+                      {error, ?ERRT_BAD_REQUEST(Lang, Txt)};
                   Fields ->
                       set_sm_form(User, Server, <<"config">>, Request, Fields)
                 end;
-            true -> {error, ?ERR_BAD_REQUEST}
+            true ->
+               Txt = <<"Incorrect action or data form">>,
+               {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
          end
     end;
 adhoc_sm_commands(Acc, _From, _To, _Request) -> Acc.
@@ -2135,12 +2204,16 @@ set_sm_form(User, Server, <<"config">>,
            {value, {_, [Password]}} ->
                ejabberd_auth:set_password(User, Server, Password),
                adhoc:produce_response(Response);
-           _ -> {error, ?ERR_NOT_ACCEPTABLE}
+           _ ->
+               Txt = <<"No 'password' found in data form">>,
+               {error, ?ERRT_NOT_ACCEPTABLE(Lang, Txt)}
          end;
       {value, {_, [<<"remove">>]}} ->
          catch ejabberd_auth:remove_user(User, Server),
          adhoc:produce_response(Response);
-      _ -> {error, ?ERR_NOT_ACCEPTABLE}
+      _ ->
+         Txt = <<"Incorrect value of 'action' in data form">>,
+         {error, ?ERRT_NOT_ACCEPTABLE(Lang, Txt)}
     end;
 set_sm_form(_User, _Server, _Node, _Request, _Fields) ->
     {error, ?ERR_SERVICE_UNAVAILABLE}.
index 734e90d367f2d814946a7e9e0359a356132153ec..0d5abcb4bba20ceb513edcc5e560e157626e5300 100644 (file)
@@ -150,7 +150,8 @@ process_local_iq_items(From, To,
                       #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
     case Type of
       set ->
-         IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
+         Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+         IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
       get ->
          Node = fxml:get_tag_attr_s(<<"node">>, SubEl),
          Host = To#jid.lserver,
@@ -177,7 +178,8 @@ process_local_iq_info(From, To,
                      #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
     case Type of
       set ->
-         IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
+         Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+         IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
       get ->
          Host = To#jid.lserver,
          Node = fxml:get_tag_attr_s(<<"node">>, SubEl),
@@ -229,10 +231,12 @@ get_local_features(Acc, _From, To, <<>>, _Lang) ->
      ets:select(disco_features,
                [{{{'_', Host}}, [], ['$_']}])
        ++ Feats};
-get_local_features(Acc, _From, _To, _Node, _Lang) ->
+get_local_features(Acc, _From, _To, _Node, Lang) ->
     case Acc of
       {result, _Features} -> Acc;
-      empty -> {error, ?ERR_ITEM_NOT_FOUND}
+      empty ->
+           Txt = <<"No features available">>,
+           {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)}
     end.
 
 features_to_xml(FeatureList) ->
@@ -271,8 +275,8 @@ get_local_services(Acc, _From, To, <<>>, _Lang) ->
 get_local_services({result, _} = Acc, _From, _To, _Node,
                   _Lang) ->
     Acc;
-get_local_services(empty, _From, _To, _Node, _Lang) ->
-    {error, ?ERR_ITEM_NOT_FOUND}.
+get_local_services(empty, _From, _To, _Node, Lang) ->
+    {error, ?ERRT_ITEM_NOT_FOUND(Lang, <<"No services available">>)}.
 
 get_vh_services(Host) ->
     Hosts = lists:sort(fun (H1, H2) ->
@@ -300,7 +304,8 @@ process_sm_iq_items(From, To,
                    #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
     case Type of
       set ->
-         IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
+         Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+         IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
       get ->
          case is_presence_subscribed(From, To) of
            true ->
@@ -325,8 +330,9 @@ process_sm_iq_items(From, To,
                      IQ#iq{type = error, sub_el = [SubEl, Error]}
                end;
            false ->
+               Txt = <<"Not subscribed">>,
                IQ#iq{type = error,
-                     sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]}
+                     sub_el = [SubEl, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)]}
          end
     end.
 
@@ -347,12 +353,14 @@ get_sm_items(Acc, From,
 get_sm_items({result, _} = Acc, _From, _To, _Node,
             _Lang) ->
     Acc;
-get_sm_items(empty, From, To, _Node, _Lang) ->
+get_sm_items(empty, From, To, _Node, Lang) ->
     #jid{luser = LFrom, lserver = LSFrom} = From,
     #jid{luser = LTo, lserver = LSTo} = To,
     case {LFrom, LSFrom} of
       {LTo, LSTo} -> {error, ?ERR_ITEM_NOT_FOUND};
-      _ -> {error, ?ERR_NOT_ALLOWED}
+      _ ->
+           Txt = <<"Query to another users is forbidden">>,
+           {error, ?ERRT_NOT_ALLOWED(Lang, Txt)}
     end.
 
 is_presence_subscribed(#jid{luser = User, lserver = Server},
@@ -373,7 +381,8 @@ process_sm_iq_info(From, To,
                   #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
     case Type of
       set ->
-         IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
+         Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+         IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
       get ->
          case is_presence_subscribed(From, To) of
            true ->
@@ -405,8 +414,9 @@ process_sm_iq_info(From, To,
                      IQ#iq{type = error, sub_el = [SubEl, Error]}
                end;
            false ->
+               Txt = <<"Not subscribed">>,
                IQ#iq{type = error,
-                     sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]}
+                     sub_el = [SubEl, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)]}
          end
     end.
 
@@ -423,12 +433,14 @@ get_sm_identity(Acc, _From,
        _ -> []
       end.
 
-get_sm_features(empty, From, To, _Node, _Lang) ->
+get_sm_features(empty, From, To, _Node, Lang) ->
     #jid{luser = LFrom, lserver = LSFrom} = From,
     #jid{luser = LTo, lserver = LSTo} = To,
     case {LFrom, LSFrom} of
       {LTo, LSTo} -> {error, ?ERR_ITEM_NOT_FOUND};
-      _ -> {error, ?ERR_NOT_ALLOWED}
+      _ ->
+           Txt = <<"Query to another users is forbidden">>,
+           {error, ?ERRT_NOT_ALLOWED(Lang, Txt)}
     end;
 get_sm_features(Acc, _From, _To, _Node, _Lang) -> Acc.
 
index d5cd01353e85a506d351a9a3064b026876f03947..f6e452d82ff9d4c1bd38f2028cdea4fffa350502 100644 (file)
@@ -304,8 +304,9 @@ do_route1(Host, ServerHost, From, To, Packet) ->
                                                                        Lang)}]},
                            Res = jlib:iq_to_xml(ResIQ);
                        _ ->
-                           Res = jlib:make_error_reply(Packet,
-                                                       ?ERR_ITEM_NOT_FOUND)
+                           Txt = <<"Node not found">>,
+                           Res = jlib:make_error_reply(
+                                   Packet, ?ERRT_ITEM_NOT_FOUND(Lang, Txt))
                      end,
                      ejabberd_router:route(To, From, Res);
                  #iq{xmlns = ?NS_REGISTER} = IQ ->
@@ -319,7 +320,7 @@ do_route1(Host, ServerHost, From, To, Packet) ->
                                              attrs = [{<<"xmlns">>, XMLNS}],
                                              children = iq_get_vcard(Lang)}]},
                      ejabberd_router:route(To, From, jlib:iq_to_xml(Res));
-                 #iq{type = set, xmlns = ?NS_COMMANDS, lang = _Lang,
+                 #iq{type = set, xmlns = ?NS_COMMANDS, lang = Lang,
                      sub_el = SubEl} =
                      IQ ->
                      Request = adhoc:parse_request(IQ),
@@ -348,8 +349,9 @@ do_route1(Host, ServerHost, From, To, Packet) ->
                               true -> ok
                            end;
                        _ ->
-                           Err = jlib:make_error_reply(Packet,
-                                                       ?ERR_ITEM_NOT_FOUND),
+                           Txt = <<"Node not found">>,
+                           Err = jlib:make_error_reply(
+                                   Packet, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)),
                            ejabberd_router:route(To, From, Err)
                      end;
                  #iq{} = _IQ ->
@@ -407,12 +409,14 @@ do_route1(Host, ServerHost, From, To, Packet) ->
                      ok
                end;
            _ ->
+               Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
                case str:tokens(ChanServ, <<"!">>) of
                  [<<_, _/binary>> = Nick, <<_, _/binary>> = Server] ->
                      case ets:lookup(irc_connection, {From, Server, Host}) of
                        [] ->
-                           Err = jlib:make_error_reply(Packet,
-                                                       ?ERR_SERVICE_UNAVAILABLE),
+                           Txt = <<"IRC connection not found">>,
+                           Err = jlib:make_error_reply(
+                                   Packet, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)),
                            ejabberd_router:route(To, From, Err);
                        [R] ->
                            Pid = R#irc_connection.pid,
@@ -421,7 +425,9 @@ do_route1(Host, ServerHost, From, To, Packet) ->
                            ok
                      end;
                  _ ->
-                     Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST),
+                     Txt = <<"Failed to parse chanserv">>,
+                     Err = jlib:make_error_reply(
+                             Packet, ?ERRT_BAD_REQUEST(Lang, Txt)),
                      ejabberd_router:route(To, From, Err)
                end
          end
@@ -532,8 +538,9 @@ process_irc_register(ServerHost, Host, From, _To,
          XDataEl = find_xdata_el(SubEl),
          case XDataEl of
            false ->
+               Txt1 = <<"No data form found">>,
                IQ#iq{type = error,
-                     sub_el = [SubEl, ?ERR_NOT_ACCEPTABLE]};
+                     sub_el = [SubEl, ?ERRT_NOT_ACCEPTABLE(Lang, Txt1)]};
            #xmlel{attrs = Attrs} ->
                case fxml:get_attr_s(<<"type">>, Attrs) of
                  <<"cancel">> ->
@@ -546,8 +553,9 @@ process_irc_register(ServerHost, Host, From, _To,
                      XData = jlib:parse_xdata_submit(XDataEl),
                      case XData of
                        invalid ->
+                           Txt2 = <<"Incorrect data form">>,
                            IQ#iq{type = error,
-                                 sub_el = [SubEl, ?ERR_BAD_REQUEST]};
+                                 sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt2)]};
                        _ ->
                            Node = str:tokens(fxml:get_tag_attr_s(<<"node">>,
                                                                 SubEl),
@@ -567,7 +575,9 @@ process_irc_register(ServerHost, Host, From, _To,
                            end
                      end;
                  _ ->
-                     IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]}
+                     Txt3 = <<"Incorrect value of 'type' attribute">>,
+                     IQ#iq{type = error,
+                           sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt3)]}
                end
          end;
       get ->
@@ -629,7 +639,9 @@ get_form(ServerHost, Host, From, [], Lang) ->
     #jid{user = User, server = Server} = From,
     DefaultEncoding = get_default_encoding(Host),
     Customs = case get_data(ServerHost, Host, From) of
-               error -> {error, ?ERR_INTERNAL_SERVER_ERROR};
+               error ->
+                     Txt1 = <<"Database failure">>,
+                     {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt1)};
                empty -> {User, []};
                Data -> get_username_and_connection_params(Data)
              end,
@@ -763,7 +775,7 @@ set_data(LServer, Host, From, Data, odbc) ->
        end,
     ejabberd_odbc:sql_transaction(LServer, F).
 
-set_form(ServerHost, Host, From, [], _Lang, XData) ->
+set_form(ServerHost, Host, From, [], Lang, XData) ->
     case {lists:keysearch(<<"username">>, 1, XData),
          lists:keysearch(<<"connections_params">>, 1, XData)}
        of
@@ -781,11 +793,11 @@ set_form(ServerHost, Host, From, [], _Lang, XData) ->
                                     {connections_params, ConnectionsParams}])
                          of
                        {atomic, _} -> {result, []};
-                       _ -> {error, ?ERR_NOT_ACCEPTABLE}
+                       _ -> {error, ?ERRT_NOT_ACCEPTABLE(Lang, <<"Database failure">>)}
                      end;
-                 _ -> {error, ?ERR_NOT_ACCEPTABLE}
+                 _ -> {error, ?ERRT_NOT_ACCEPTABLE(Lang, <<"Parse error">>)}
                end;
-           _ -> {error, ?ERR_NOT_ACCEPTABLE}
+           _ -> {error, ?ERRT_NOT_ACCEPTABLE(Lang, <<"Scan error">>)}
          end;
       _ -> {error, ?ERR_NOT_ACCEPTABLE}
     end;
@@ -909,7 +921,9 @@ adhoc_join(From, To,
                                                  elements = [Form]});
        true ->
           case jlib:parse_xdata_submit(XData) of
-            invalid -> {error, ?ERR_BAD_REQUEST};
+            invalid ->
+                Txt1 = <<"Incorrect data form">>,
+                {error, ?ERRT_BAD_REQUEST(Lang, Txt1)};
             Fields ->
                 Channel = case lists:keysearch(<<"channel">>, 1, Fields)
                               of
@@ -998,7 +1012,8 @@ adhoc_register(ServerHost, From, To,
        true ->
           case jlib:parse_xdata_submit(XData) of
             invalid ->
-                Error = {error, ?ERR_BAD_REQUEST},
+                Txt1 = <<"Incorrect data form">>,
+                Error = {error, ?ERRT_BAD_REQUEST(Lang, Txt1)},
                 Username = false,
                 ConnectionsParams = false;
             Fields ->
@@ -1021,7 +1036,9 @@ adhoc_register(ServerHost, From, To,
             {atomic, _} ->
                 adhoc:produce_response(Request,
                                        #adhoc_response{status = completed});
-            _ -> {error, ?ERR_INTERNAL_SERVER_ERROR}
+            _ ->
+                Txt2 = <<"Database failure">>,
+                {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt2)}
           end;
        true ->
           Form = generate_adhoc_register_form(Lang, Username,
index e67a02cc289cf9db547a11a248f17176cf9598ac..009a1cb06650be36ddf415abcabe62faffa5bded 100644 (file)
@@ -152,8 +152,7 @@ process_sm_iq(From, To,
                     of
                   allow -> get_last_iq(IQ, SubEl, User, Server);
                   deny ->
-                      Txt = <<"Denied by privacy lists">>,
-                      IQ#iq{type = error, sub_el = [SubEl, ?ERRT_FORBIDDEN(Lang, Txt)]}
+                      IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]}
                 end;
             true ->
                 Txt = <<"Not subscribed">>,
index 06fdf325f3af5a69e953e6037451c3e03ab81e6b..c9c7857574c312a73ac2ed948ea771bde1a2fef3 100644 (file)
@@ -252,7 +252,7 @@ normal_state({route, From, <<"">>,
                IsVoiceApprovement = is_voice_approvement(Els) and
                                       not is_visitor(From, StateData),
                if IsInvitation ->
-                      case catch check_invitation(From, Els, Lang, StateData)
+                      case catch check_invitation(From, Packet, Lang, StateData)
                           of
                         {error, Error} ->
                             Err = jlib:make_error_reply(Packet, Error),
@@ -433,9 +433,11 @@ normal_state({route, From, <<"">>,
                                   process_iq_owner(From, Type, Lang, SubEl, StateData);
                               ?NS_DISCO_INFO ->
                                   case fxml:get_attr(<<"node">>, Attrs) of
-                                         false -> process_iq_disco_info(From, Type, Lang, StateData);
-                                         {value, _} -> {error, ?ERR_SERVICE_UNAVAILABLE}
-                                       end;
+                                      false -> process_iq_disco_info(From, Type, Lang, StateData);
+                                      {value, _} ->
+                                          Txt = <<"Disco info is not available for this node">>,
+                                          {error, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)}
+                                  end;
                               ?NS_DISCO_ITEMS ->
                                   process_iq_disco_items(From, Type, Lang, StateData);
                               ?NS_VCARD ->
@@ -817,8 +819,9 @@ handle_info({captcha_failed, From}, normal_state,
                   of
                 {ok, {Nick, Packet}} ->
                     Robots = (?DICT):erase(From, StateData#state.robots),
-                    Err = jlib:make_error_reply(Packet,
-                                                ?ERR_NOT_AUTHORIZED),
+                    Txt = <<"The CAPTCHA verification has failed">>,
+                    Err = jlib:make_error_reply(
+                            Packet, ?ERRT_NOT_AUTHORIZED(?MYLANG, Txt)),
                     ejabberd_router:route % TODO: s/Nick/""/
                                 (jid:replace_resource(StateData#state.jid,
                                                            Nick),
@@ -1807,6 +1810,22 @@ add_new_user(From, Nick,
                               StateData#state.host, From, Nick),
          get_default_role(Affiliation, StateData)}
        of
+      {false, _, _, _} when NUsers >= MaxUsers orelse NUsers >= MaxAdminUsers ->
+         Txt = <<"Too many users in this conference">>,
+         Err = jlib:make_error_reply(Packet,
+                                     ?ERRT_RESOURCE_CONSTRAINT(Lang, Txt)),
+         ejabberd_router:route % TODO: s/Nick/""/
+                     (jid:replace_resource(StateData#state.jid, Nick),
+                      From, Err),
+         StateData;
+      {false, _, _, _} when NConferences >= MaxConferences ->
+         Txt = <<"You have joined too many conferences">>,
+         Err = jlib:make_error_reply(Packet,
+                                     ?ERRT_RESOURCE_CONSTRAINT(Lang, Txt)),
+         ejabberd_router:route % TODO: s/Nick/""/
+                     (jid:replace_resource(StateData#state.jid, Nick),
+                      From, Err),
+         StateData;
       {false, _, _, _} ->
          Err = jlib:make_error_reply(Packet,
                                      ?ERR_SERVICE_UNAVAILABLE),
@@ -2555,14 +2574,18 @@ process_iq_admin(From, set, Lang, SubEl, StateData) ->
     process_admin_items_set(From, Items, Lang, StateData);
 process_iq_admin(From, get, Lang, SubEl, StateData) ->
     case fxml:get_subtag(SubEl, <<"item">>) of
-      false -> {error, ?ERR_BAD_REQUEST};
+      false ->
+         Txt = <<"No 'item' element found">>,
+         {error, ?ERRT_BAD_REQUEST(Lang, Txt)};
       Item ->
          FAffiliation = get_affiliation(From, StateData),
          FRole = get_role(From, StateData),
          case fxml:get_tag_attr(<<"role">>, Item) of
            false ->
                case fxml:get_tag_attr(<<"affiliation">>, Item) of
-                 false -> {error, ?ERR_BAD_REQUEST};
+                 false ->
+                     Txt = <<"No 'affiliation' attribute found">>,
+                     {error, ?ERRT_BAD_REQUEST(Lang, Txt)};
                  {value, StrAffiliation} ->
                      case catch list_to_affiliation(StrAffiliation) of
                        {'EXIT', _} -> {error, ?ERR_BAD_REQUEST};
@@ -2583,7 +2606,9 @@ process_iq_admin(From, get, Lang, SubEl, StateData) ->
                end;
            {value, StrRole} ->
                case catch list_to_role(StrRole) of
-                 {'EXIT', _} -> {error, ?ERR_BAD_REQUEST};
+                 {'EXIT', _} ->
+                     Txt = <<"Incorrect value of 'role' attribute">>,
+                     {error, ?ERRT_BAD_REQUEST(Lang, Txt)};
                  SRole ->
                      if FRole == moderator ->
                             Items = items_with_role(SRole, StateData),
@@ -2780,7 +2805,9 @@ find_changed_items(UJID, UAffiliation, URole,
                             {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)};
                         J -> {value, J}
                       end;
-                  _ -> {error, ?ERR_BAD_REQUEST}
+                  _ ->
+                      Txt1 = <<"No 'nick' attribute found">>,
+                      {error, ?ERRT_BAD_REQUEST(Lang, Txt1)}
                 end
           end,
     case TJID of
@@ -2790,7 +2817,9 @@ find_changed_items(UJID, UAffiliation, URole,
          case fxml:get_attr(<<"role">>, Attrs) of
            false ->
                case fxml:get_attr(<<"affiliation">>, Attrs) of
-                 false -> {error, ?ERR_BAD_REQUEST};
+                 false ->
+                     Txt2 = <<"No 'affiliation' attribute found">>,
+                     {error, ?ERRT_BAD_REQUEST(Lang, Txt2)};
                  {value, StrAffiliation} ->
                      case catch list_to_affiliation(StrAffiliation) of
                        {'EXIT', _} ->
@@ -2839,7 +2868,9 @@ find_changed_items(UJID, UAffiliation, URole,
                                  find_changed_items(UJID, UAffiliation, URole,
                                                     Items, Lang, StateData,
                                                     [MoreRes | Res]);
-                             false -> {error, ?ERR_NOT_ALLOWED}
+                             false ->
+                                Txt3 = <<"Changing role/affiliation is not allowed">>,
+                                {error, ?ERRT_NOT_ALLOWED(Lang, Txt3)}
                            end
                      end
                end;
@@ -2885,7 +2916,9 @@ find_changed_items(UJID, UAffiliation, URole,
                            find_changed_items(UJID, UAffiliation, URole, Items,
                                               Lang, StateData,
                                               [MoreRes | Res]);
-                       _ -> {error, ?ERR_NOT_ALLOWED}
+                       _ ->
+                          Txt4 = <<"Changing role/affiliation is not allowed">>,
+                          {error, ?ERRT_NOT_ALLOWED(Lang, Txt4)}
                      end
                end
          end;
@@ -3143,10 +3176,12 @@ process_iq_owner(From, set, Lang, SubEl, StateData) ->
                                 andalso
                                 is_password_settings_correct(XEl, StateData)
                          of
-                       true -> set_config(XEl, StateData);
+                       true -> set_config(XEl, StateData, Lang);
                        false -> {error, ?ERR_NOT_ACCEPTABLE}
                      end;
-                 _ -> {error, ?ERR_BAD_REQUEST}
+                 _ ->
+                    Txt = <<"Incorrect data form">>,
+                    {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
                end;
            [#xmlel{name = <<"destroy">>} = SubEl1] ->
                ?INFO_MSG("Destroyed MUC room ~s by the owner ~s",
@@ -3170,7 +3205,9 @@ process_iq_owner(From, get, Lang, SubEl, StateData) ->
            [] -> get_config(Lang, StateData, From);
            [Item] ->
                case fxml:get_tag_attr(<<"affiliation">>, Item) of
-                 false -> {error, ?ERR_BAD_REQUEST};
+                 false ->
+                     Txt = <<"No 'affiliation' attribute found">>,
+                     {error, ?ERRT_BAD_REQUEST(Lang, Txt)};
                  {value, StrAffiliation} ->
                      case catch list_to_affiliation(StrAffiliation) of
                        {'EXIT', _} ->
@@ -3642,10 +3679,10 @@ get_config(Lang, StateData, From) ->
             children = Res}],
      StateData}.
 
-set_config(XEl, StateData) ->
+set_config(XEl, StateData, Lang) ->
     XData = jlib:parse_xdata_submit(XEl),
     case XData of
-      invalid -> {error, ?ERR_BAD_REQUEST};
+      invalid -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Incorrect data form">>)};
       _ ->
          case set_xoption(XData, StateData#state.config) of
            #config{} = Config ->
@@ -3675,14 +3712,20 @@ set_config(XEl, StateData) ->
          <<"1">> -> set_xoption(Opts, Config#config{Opt = true});
          <<"true">> ->
              set_xoption(Opts, Config#config{Opt = true});
-         _ -> {error, ?ERR_BAD_REQUEST}
+         _ ->
+             Txt = <<"Value of '~s' should be boolean">>,
+             ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
+             {error, ?ERRT_BAD_REQUEST(?MYLANG, ErrTxt)}
        end).
 
 -define(SET_NAT_XOPT(Opt, Val),
        case catch jlib:binary_to_integer(Val) of
          I when is_integer(I), I > 0 ->
              set_xoption(Opts, Config#config{Opt = I});
-         _ -> {error, ?ERR_BAD_REQUEST}
+         _ ->
+             Txt = <<"Value of '~s' should be integer">>,
+             ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
+             {error, ?ERRT_BAD_REQUEST(?MYLANG, ErrTxt)}
        end).
 
 -define(SET_STRING_XOPT(Opt, Val),
@@ -3735,7 +3778,10 @@ set_xoption([{<<"allow_private_messages_from_visitors">>,
       <<"nobody">> ->
          ?SET_STRING_XOPT(allow_private_messages_from_visitors,
                           nobody);
-      _ -> {error, ?ERR_BAD_REQUEST}
+      _ ->
+         Txt = <<"Value of 'allow_private_messages_from_visitors' "
+                 "should be anyone|moderators|nobody">>,
+         {error, ?ERRT_BAD_REQUEST(?MYLANG, Txt)}
     end;
 set_xoption([{<<"muc#roomconfig_allowvisitorstatus">>,
              [Val]}
@@ -3803,7 +3849,10 @@ set_xoption([{<<"muc#roomconfig_presencebroadcast">>, Vals} | Opts],
                   end
           end, {false, false, false}, Vals),
     case Roles of
-        error -> {error, ?ERR_BAD_REQUEST};
+        error ->
+           Txt = <<"Value of 'muc#roomconfig_presencebroadcast' should "
+                   "be moderator|participant|visitor">>,
+           {error, ?ERRT_BAD_REQUEST(?MYLANG, Txt)};
         {M, P, V} ->
             Res =
                 if M -> [moderator]; true -> [] end ++
@@ -3831,7 +3880,10 @@ set_xoption([{<<"muc#roomconfig_whois">>, [Val]}
       <<"anyone">> ->
          ?SET_BOOL_XOPT(anonymous,
                         (iolist_to_binary(integer_to_list(0))));
-      _ -> {error, ?ERR_BAD_REQUEST}
+      _ ->
+         Txt = <<"Value of 'muc#roomconfig_whois' should be "
+                 "moderators|anyone">>,
+         {error, ?ERRT_BAD_REQUEST(?MYLANG, Txt)}
     end;
 set_xoption([{<<"muc#roomconfig_maxusers">>, [Val]}
             | Opts],
@@ -3854,8 +3906,10 @@ set_xoption([{<<"muc#roomconfig_captcha_whitelist">>,
     ?SET_JIDMULTI_XOPT(captcha_whitelist, JIDs);
 set_xoption([{<<"FORM_TYPE">>, _} | Opts], Config) ->
     set_xoption(Opts, Config);
-set_xoption([_ | _Opts], _Config) ->
-    {error, ?ERR_BAD_REQUEST}.
+set_xoption([{Opt, _Vals} | _Opts], _Config) ->
+    Txt = <<"Unknown option '~s'">>,
+    ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
+    {error, ?ERRT_BAD_REQUEST(?MYLANG, ErrTxt)}.
 
 change_config(Config, StateData) ->
     send_config_change_info(Config, StateData),
@@ -4128,8 +4182,9 @@ destroy_room(DEl, StateData) ->
          false -> ?FEATURE(Fiffalse)
        end).
 
-process_iq_disco_info(_From, set, _Lang, _StateData) ->
-    {error, ?ERR_NOT_ALLOWED};
+process_iq_disco_info(_From, set, Lang, _StateData) ->
+    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    {error, ?ERRT_NOT_ALLOWED(Lang, Txt)};
 process_iq_disco_info(_From, get, Lang, StateData) ->
     Config = StateData#state.config,
     {result,
@@ -4199,9 +4254,10 @@ iq_disco_info_extras(Lang, StateData) ->
                         <<"muc#roominfo_occupants">>,
                         (iolist_to_binary(integer_to_list(Len))))]}].
 
-process_iq_disco_items(_From, set, _Lang, _StateData) ->
-    {error, ?ERR_NOT_ALLOWED};
-process_iq_disco_items(From, get, _Lang, StateData) ->
+process_iq_disco_items(_From, set, Lang, _StateData) ->
+    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    {error, ?ERRT_NOT_ALLOWED(Lang, Txt)};
+process_iq_disco_items(From, get, Lang, StateData) ->
     case (StateData#state.config)#config.public_list of
       true ->
          {result, get_mucroom_disco_items(StateData), StateData};
@@ -4209,18 +4265,26 @@ process_iq_disco_items(From, get, _Lang, StateData) ->
          case is_occupant_or_admin(From, StateData) of
            true ->
                {result, get_mucroom_disco_items(StateData), StateData};
-           _ -> {error, ?ERR_FORBIDDEN}
+           _ ->
+               Txt = <<"Only occupants or administrators can perform this query">>,
+               {error, ?ERRT_FORBIDDEN(Lang, Txt)}
          end
     end.
 
-process_iq_captcha(_From, get, _Lang, _SubEl,
+process_iq_captcha(_From, get, Lang, _SubEl,
                   _StateData) ->
-    {error, ?ERR_NOT_ALLOWED};
-process_iq_captcha(_From, set, _Lang, SubEl,
+    Txt = <<"Value 'get' of 'type' attribute is not allowed">>,
+    {error, ?ERRT_NOT_ALLOWED(Lang, Txt)};
+process_iq_captcha(_From, set, Lang, SubEl,
                   StateData) ->
     case ejabberd_captcha:process_reply(SubEl) of
       ok -> {result, [], StateData};
-      _ -> {error, ?ERR_NOT_ACCEPTABLE}
+      {error, malformed} ->
+           Txt = <<"Incorrect CAPTCHA submit">>,
+           {error, ?ERRT_BAD_REQUEST(Lang, Txt)};
+      _ ->
+           Txt = <<"The CAPTCHA verification has failed">>,
+           {error, ?ERRT_NOT_ALLOWED(Lang, Txt)}
     end.
 
 process_iq_vcard(_From, get, _Lang, _SubEl, StateData) ->
@@ -4442,33 +4506,38 @@ is_invitation(Els) ->
                end,
                false, Els).
 
-check_invitation(From, Els, Lang, StateData) ->
+check_invitation(From, Packet, Lang, StateData) ->
     FAffiliation = get_affiliation(From, StateData),
     CanInvite =
        (StateData#state.config)#config.allow_user_invites
          orelse
          FAffiliation == admin orelse FAffiliation == owner,
-    InviteEl = case fxml:remove_cdata(Els) of
-                [#xmlel{name = <<"x">>, children = Els1} = XEl] ->
-                    case fxml:get_tag_attr_s(<<"xmlns">>, XEl) of
-                      ?NS_MUC_USER -> ok;
-                      _ -> throw({error, ?ERR_BAD_REQUEST})
-                    end,
-                    case fxml:remove_cdata(Els1) of
-                      [#xmlel{name = <<"invite">>} = InviteEl1] -> InviteEl1;
-                      _ -> throw({error, ?ERR_BAD_REQUEST})
-                    end;
-                _ -> throw({error, ?ERR_BAD_REQUEST})
+    InviteEl = case fxml:get_subtag_with_xmlns(Packet, <<"x">>, ?NS_MUC_USER) of
+                  false ->
+                      Txt1 = <<"No 'x' element found">>,
+                      throw({error, ?ERRT_BAD_REQUEST(Lang, Txt1)});
+                  XEl ->
+                      case fxml:get_subtag(XEl, <<"invite">>) of
+                          false ->
+                              Txt2 = <<"No 'invite' element found">>,
+                              throw({error, ?ERRT_BAD_REQUEST(Lang, Txt2)});
+                          InviteEl1 ->
+                              InviteEl1
+                      end
               end,
     JID = case
            jid:from_string(fxml:get_tag_attr_s(<<"to">>,
                                                  InviteEl))
              of
-           error -> throw({error, ?ERR_JID_MALFORMED});
+           error ->
+                 Txt = <<"Incorrect value of 'to' attribute">>,
+                 throw({error, ?ERRT_JID_MALFORMED(Lang, Txt)});
            JID1 -> JID1
          end,
     case CanInvite of
-      false -> throw({error, ?ERR_NOT_ALLOWED});
+      false ->
+         Txt3 = <<"Invitations are not allowed in this conference">>,
+         throw({error, ?ERRT_NOT_ALLOWED(Lang, Txt3)});
       true ->
          Reason = fxml:get_path_s(InviteEl,
                                  [{elem, <<"reason">>}, cdata]),
index 193befe822460e83f43e8079f4768a28e1832d54..ea36fed25c089a4b2dbfbb92aa962d1e162581f1 100644 (file)
@@ -105,27 +105,29 @@ process_iq(_From, _To, IQ) ->
     SubEl = IQ#iq.sub_el,
     IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}.
 
-process_iq_get(_, From, _To, #iq{sub_el = SubEl},
+process_iq_get(_, From, _To, #iq{lang = Lang, sub_el = SubEl},
               #userlist{name = Active}) ->
     #jid{luser = LUser, lserver = LServer} = From,
     #xmlel{children = Els} = SubEl,
     case fxml:remove_cdata(Els) of
-      [] -> process_lists_get(LUser, LServer, Active);
+      [] -> process_lists_get(LUser, LServer, Active, Lang);
       [#xmlel{name = Name, attrs = Attrs}] ->
          case Name of
            <<"list">> ->
                ListName = fxml:get_attr(<<"name">>, Attrs),
-               process_list_get(LUser, LServer, ListName);
-           _ -> {error, ?ERR_BAD_REQUEST}
+               process_list_get(LUser, LServer, ListName, Lang);
+           _ ->
+                 Txt = <<"Unsupported tag name">>,
+                 {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
          end;
-      _ -> {error, ?ERR_BAD_REQUEST}
+      _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Too many elements">>)}
     end.
 
-process_lists_get(LUser, LServer, Active) ->
-    case process_lists_get(LUser, LServer, Active,
+process_lists_get(LUser, LServer, Active, Lang) ->
+    case process_lists_get_db(LUser, LServer, Active,
                           gen_mod:db_type(LServer, ?MODULE))
        of
-      error -> {error, ?ERR_INTERNAL_SERVER_ERROR};
+      error -> {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)};
       {_Default, []} ->
          {result,
           [#xmlel{name = <<"query">>,
@@ -151,7 +153,7 @@ process_lists_get(LUser, LServer, Active) ->
                   children = ADItems}]}
     end.
 
-process_lists_get(LUser, LServer, _Active, mnesia) ->
+process_lists_get_db(LUser, LServer, _Active, mnesia) ->
     case catch mnesia:dirty_read(privacy, {LUser, LServer})
        of
       {'EXIT', _Reason} -> error;
@@ -165,7 +167,7 @@ process_lists_get(LUser, LServer, _Active, mnesia) ->
                             Lists),
          {Default, LItems}
     end;
-process_lists_get(LUser, LServer, _Active, riak) ->
+process_lists_get_db(LUser, LServer, _Active, riak) ->
     case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of
         {ok, #privacy{default = Default, lists = Lists}} ->
             LItems = lists:map(fun ({N, _}) ->
@@ -180,7 +182,7 @@ process_lists_get(LUser, LServer, _Active, riak) ->
         {error, _} ->
             error
     end;
-process_lists_get(LUser, LServer, _Active, odbc) ->
+process_lists_get_db(LUser, LServer, _Active, odbc) ->
     Default = case catch sql_get_default_privacy_list(LUser, LServer) of
                {selected, []} -> none;
                {selected, [{DefName}]} -> DefName;
@@ -198,11 +200,11 @@ process_lists_get(LUser, LServer, _Active, odbc) ->
       _ -> error
     end.
 
-process_list_get(LUser, LServer, {value, Name}) ->
-    case process_list_get(LUser, LServer, Name,
+process_list_get(LUser, LServer, {value, Name}, Lang) ->
+    case process_list_get_db(LUser, LServer, Name,
                          gen_mod:db_type(LServer, ?MODULE))
        of
-      error -> {error, ?ERR_INTERNAL_SERVER_ERROR};
+      error -> {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)};
       not_found -> {error, ?ERR_ITEM_NOT_FOUND};
       Items ->
          LItems = lists:map(fun item_to_xml/1, Items),
@@ -213,10 +215,10 @@ process_list_get(LUser, LServer, {value, Name}) ->
                       [#xmlel{name = <<"list">>, attrs = [{<<"name">>, Name}],
                               children = LItems}]}]}
     end;
-process_list_get(_LUser, _LServer, false) ->
+process_list_get(_LUser, _LServer, false, _Lang) ->
     {error, ?ERR_BAD_REQUEST}.
 
-process_list_get(LUser, LServer, Name, mnesia) ->
+process_list_get_db(LUser, LServer, Name, mnesia) ->
     case catch mnesia:dirty_read(privacy, {LUser, LServer})
        of
       {'EXIT', _Reason} -> error;
@@ -227,7 +229,7 @@ process_list_get(LUser, LServer, Name, mnesia) ->
            _ -> not_found
          end
     end;
-process_list_get(LUser, LServer, Name, riak) ->
+process_list_get_db(LUser, LServer, Name, riak) ->
     case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of
         {ok, #privacy{lists = Lists}} ->
             case lists:keysearch(Name, 1, Lists) of
@@ -239,7 +241,7 @@ process_list_get(LUser, LServer, Name, riak) ->
         {error, _} ->
             error
     end;
-process_list_get(LUser, LServer, Name, odbc) ->
+process_list_get_db(LUser, LServer, Name, odbc) ->
     case catch sql_get_privacy_list_id(LUser, LServer, Name) of
       {selected, []} -> not_found;
       {selected, [{ID}]} ->
@@ -332,7 +334,7 @@ list_to_action(S) ->
       <<"deny">> -> deny
     end.
 
-process_iq_set(_, From, _To, #iq{sub_el = SubEl}) ->
+process_iq_set(_, From, _To, #iq{lang = Lang, sub_el = SubEl}) ->
     #jid{luser = LUser, lserver = LServer} = From,
     #xmlel{children = Els} = SubEl,
     case fxml:remove_cdata(Els) of
@@ -342,27 +344,30 @@ process_iq_set(_, From, _To, #iq{sub_el = SubEl}) ->
          case Name of
            <<"list">> ->
                process_list_set(LUser, LServer, ListName,
-                                fxml:remove_cdata(SubEls));
+                                fxml:remove_cdata(SubEls), Lang);
            <<"active">> ->
                process_active_set(LUser, LServer, ListName);
            <<"default">> ->
-               process_default_set(LUser, LServer, ListName);
-           _ -> {error, ?ERR_BAD_REQUEST}
+               process_default_set(LUser, LServer, ListName, Lang);
+           _ ->
+               Txt = <<"Unsupported tag name">>,
+               {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
          end;
       _ -> {error, ?ERR_BAD_REQUEST}
     end.
 
-process_default_set(LUser, LServer, Value) ->
-    case process_default_set(LUser, LServer, Value,
+process_default_set(LUser, LServer, Value, Lang) ->
+    case process_default_set_db(LUser, LServer, Value,
                             gen_mod:db_type(LServer, ?MODULE))
        of
-      {atomic, error} -> {error, ?ERR_INTERNAL_SERVER_ERROR};
+      {atomic, error} ->
+           {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)};
       {atomic, not_found} -> {error, ?ERR_ITEM_NOT_FOUND};
       {atomic, ok} -> {result, []};
       _ -> {error, ?ERR_INTERNAL_SERVER_ERROR}
     end.
 
-process_default_set(LUser, LServer, {value, Name},
+process_default_set_db(LUser, LServer, {value, Name},
                    mnesia) ->
     F = fun () ->
                case mnesia:read({privacy, {LUser, LServer}}) of
@@ -378,7 +383,7 @@ process_default_set(LUser, LServer, {value, Name},
                end
        end,
     mnesia:transaction(F);
-process_default_set(LUser, LServer, {value, Name}, riak) ->
+process_default_set_db(LUser, LServer, {value, Name}, riak) ->
     {atomic,
      case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of
          {ok, #privacy{lists = Lists} = P} ->
@@ -393,7 +398,7 @@ process_default_set(LUser, LServer, {value, Name}, riak) ->
          {error, _} ->
              not_found
      end};
-process_default_set(LUser, LServer, {value, Name},
+process_default_set_db(LUser, LServer, {value, Name},
                    odbc) ->
     F = fun () ->
                case sql_get_privacy_list_names_t(LUser) of
@@ -406,7 +411,7 @@ process_default_set(LUser, LServer, {value, Name},
                end
        end,
     odbc_queries:sql_transaction(LServer, F);
-process_default_set(LUser, LServer, false, mnesia) ->
+process_default_set_db(LUser, LServer, false, mnesia) ->
     F = fun () ->
                case mnesia:read({privacy, {LUser, LServer}}) of
                  [] -> ok;
@@ -414,7 +419,7 @@ process_default_set(LUser, LServer, false, mnesia) ->
                end
        end,
     mnesia:transaction(F);
-process_default_set(LUser, LServer, false, riak) ->
+process_default_set_db(LUser, LServer, false, riak) ->
     {atomic,
      case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of
          {ok, R} ->
@@ -422,7 +427,7 @@ process_default_set(LUser, LServer, false, riak) ->
          {error, _} ->
              ok
      end};
-process_default_set(LUser, LServer, false, odbc) ->
+process_default_set_db(LUser, LServer, false, odbc) ->
     case catch sql_unset_default_privacy_list(LUser,
                                              LServer)
        of
@@ -588,14 +593,16 @@ set_privacy_list(LUser, LServer, Name, List, odbc) ->
        end,
     odbc_queries:sql_transaction(LServer, F).
 
-process_list_set(LUser, LServer, {value, Name}, Els) ->
+process_list_set(LUser, LServer, {value, Name}, Els, Lang) ->
     case parse_items(Els) of
       false -> {error, ?ERR_BAD_REQUEST};
       remove ->
          case remove_privacy_list(LUser, LServer, Name,
                                   gen_mod:db_type(LServer, ?MODULE))
              of
-           {atomic, conflict} -> {error, ?ERR_CONFLICT};
+           {atomic, conflict} ->
+                 Txt = <<"Cannot remove default list">>,
+                 {error, ?ERRT_CONFLICT(Lang, Txt)};
            {atomic, ok} ->
                ejabberd_sm:route(jid:make(LUser, LServer,
                                                 <<"">>),
@@ -605,7 +612,7 @@ process_list_set(LUser, LServer, {value, Name}, Els) ->
                                                          list = []},
                                                Name}}),
                {result, []};
-           _ -> {error, ?ERR_INTERNAL_SERVER_ERROR}
+           _ -> {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)}
          end;
       List ->
          case set_privacy_list(LUser, LServer, Name, List,
@@ -622,10 +629,10 @@ process_list_set(LUser, LServer, {value, Name}, Els) ->
                                                          needdb = NeedDb},
                                                Name}}),
                {result, []};
-           _ -> {error, ?ERR_INTERNAL_SERVER_ERROR}
+           _ -> {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)}
          end
     end;
-process_list_set(_LUser, _LServer, false, _Els) ->
+process_list_set(_LUser, _LServer, false, _Els, _Lang) ->
     {error, ?ERR_BAD_REQUEST}.
 
 parse_items([]) -> remove;
index 6531ed8764c53930905fd19e9a404b5b9c3de393..247b9f8c4b9dcc531626c9ab94b0d88b44f2c142 100644 (file)
@@ -1034,7 +1034,10 @@ do_route(ServerHost, Access, Plugins, Host, From, To, Packet) ->
                                none ->
                                    ok;
                                invalid ->
-                                   Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST),
+                                   Lang = fxml:get_attr_s(<<"xml:lang">>, Attrs),
+                                   Txt = <<"Incorrect authorization response">>,
+                                   Err = jlib:make_error_reply(
+                                           Packet, ?ERRT_BAD_REQUEST(Lang, Txt)),
                                    ejabberd_router:route(To, From, Err);
                                XFields ->
                                    handle_authorization_response(Host, From, To, Packet, XFields)
@@ -1418,13 +1421,14 @@ adhoc_request(Host, _ServerHost, Owner,
     send_pending_node_form(Host, Owner, Lang, Plugins);
 adhoc_request(Host, _ServerHost, Owner,
            #adhoc_request{node = ?NS_PUBSUB_GET_PENDING,
-               action = <<"execute">>, xdata = XData},
+               action = <<"execute">>, xdata = XData, lang = Lang},
            _Access, _Plugins) ->
     ParseOptions = case XData of
        #xmlel{name = <<"x">>} = XEl ->
            case jlib:parse_xdata_submit(XEl) of
                invalid ->
-                   {error, ?ERR_BAD_REQUEST};
+                   Txt = <<"Incorrect data form">>,
+                   {error, ?ERRT_BAD_REQUEST(Lang, Txt)};
                XData2 ->
                    case set_xoption(Host, XData2, []) of
                        NewOpts when is_list(NewOpts) -> {result, NewOpts};
@@ -1432,8 +1436,8 @@ adhoc_request(Host, _ServerHost, Owner,
                    end
            end;
        _ ->
-           ?INFO_MSG("Bad XForm: ~p", [XData]),
-           {error, ?ERR_BAD_REQUEST}
+           Txt = <<"No data form found">>,
+           {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
     end,
     case ParseOptions of
        {result, XForm} ->
@@ -1463,7 +1467,9 @@ send_pending_node_form(Host, Owner, _Lang, Plugins) ->
     end,
     case lists:filter(Filter, Plugins) of
        [] ->
-           {error, ?ERR_FEATURE_NOT_IMPLEMENTED};
+           Err = extended_error(?ERR_FEATURE_NOT_IMPLEMENTED,
+                                unsupported, <<"get-pending">>),
+           {error, Err};
        Ps ->
            XOpts = [#xmlel{name = <<"option">>, attrs = [],
                        children = [#xmlel{name = <<"value">>,
@@ -1504,10 +1510,11 @@ send_pending_auth_events(Host, Node, Owner) ->
                true ->
                    case node_call(Host, Type, get_affiliation, [Nidx, Owner]) of
                        {result, owner} -> node_call(Host, Type, get_node_subscriptions, [Nidx]);
-                       _ -> {error, ?ERR_FORBIDDEN}
+                       _ -> {error, ?ERRT_FORBIDDEN(?MYLANG, <<"You're not an owner">>)}
                    end;
                false ->
-                   {error, ?ERR_FEATURE_NOT_IMPLEMENTED}
+                   {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED,
+                                          unsupported, <<"get-pending">>)}
            end
     end,
     case transaction(Host, Node, Action, sync_dirty) of
@@ -1644,6 +1651,7 @@ send_authorization_approval(Host, JID, SNode, Subscription) ->
     ejabberd_router:route(service_jid(Host), JID, Stanza).
 
 handle_authorization_response(Host, From, To, Packet, XFields) ->
+    Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
     case {lists:keysearch(<<"pubsub#node">>, 1, XFields),
            lists:keysearch(<<"pubsub#subscriber_jid">>, 1, XFields),
            lists:keysearch(<<"pubsub#allow">>, 1, XFields)}
@@ -1665,7 +1673,7 @@ handle_authorization_response(Host, From, To, Packet, XFields) ->
                            {result, Subs} = node_call(Host, Type, get_subscriptions, [Nidx, Subscriber]),
                            update_auth(Host, Node, Type, Nidx, Subscriber, Allow, Subs);
                        false ->
-                           {error, ?ERR_FORBIDDEN}
+                           {error, ?ERRT_FORBIDDEN(Lang, <<"You're not an owner">>)}
                    end
            end,
            case transaction(Host, Node, Action, sync_dirty) of
@@ -1680,7 +1688,8 @@ handle_authorization_response(Host, From, To, Packet, XFields) ->
                    ejabberd_router:route(To, From, Err)
            end;
        _ ->
-           Err = jlib:make_error_reply(Packet, ?ERR_NOT_ACCEPTABLE),
+           Txt = <<"Incorrect data form">>,
+           Err = jlib:make_error_reply(Packet, ?ERRT_NOT_ACCEPTABLE(Lang, Txt)),
            ejabberd_router:route(To, From, Err)
     end.
 
@@ -1691,7 +1700,7 @@ update_auth(Host, Node, Type, Nidx, Subscriber, Allow, Subs) ->
            end,
            Subs),
     case Sub of
-       [{pending, SubId}] ->
+       [{pending, SubId}|_] ->
            NewSub = case Allow of
                true -> subscribed;
                false -> none
@@ -1700,7 +1709,8 @@ update_auth(Host, Node, Type, Nidx, Subscriber, Allow, Subs) ->
            send_authorization_approval(Host, Subscriber, Node, NewSub),
            {result, ok};
        _ ->
-           {error, ?ERR_UNEXPECTED_REQUEST}
+           Txt = <<"No pending subscriptions found">>,
+           {error, ?ERRT_UNEXPECTED_REQUEST(?MYLANG, Txt)}
     end.
 
 -define(XFIELD(Type, Label, Var, Val),
@@ -1830,7 +1840,8 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) ->
        [#xmlel{name = <<"x">>} = XEl] ->
            case jlib:parse_xdata_submit(XEl) of
                invalid ->
-                   {error, ?ERR_BAD_REQUEST};
+                   Txt = <<"Incorrect data form">>,
+                   {error, ?ERRT_BAD_REQUEST(?MYLANG, Txt)};
                XData ->
                    case set_xoption(Host, XData, node_options(Host, Type)) of
                        NewOpts when is_list(NewOpts) -> {result, NewOpts};
@@ -1839,7 +1850,8 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) ->
            end;
        _ ->
            ?INFO_MSG("Node ~p; bad configuration: ~p", [Node, Configuration]),
-           {error, ?ERR_BAD_REQUEST}
+           Txt = <<"No data form found">>,
+           {error, ?ERRT_BAD_REQUEST(?MYLANG, Txt)}
     end,
     case ParseOptions of
        {result, NodeOptions} ->
@@ -1876,7 +1888,8 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) ->
                                    Error
                            end;
                        _ ->
-                           {error, ?ERR_FORBIDDEN}
+                           Txt1 = <<"You're not allowed to create nodes">>,
+                           {error, ?ERRT_FORBIDDEN(?MYLANG, Txt1)}
                    end
            end,
            Reply = [#xmlel{name = <<"pubsub">>,
@@ -1926,7 +1939,7 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) ->
     | {error, xmlel()}
     ).
 delete_node(_Host, <<>>, _Owner) ->
-    {error, ?ERR_NOT_ALLOWED};
+    {error, ?ERRT_NOT_ALLOWED(?MYLANG, <<"No node specified">>)};
 delete_node(Host, Node, Owner) ->
     Action = fun (#pubsub_node{type = Type, id = Nidx}) ->
            case node_call(Host, Type, get_affiliation, [Nidx, Owner]) of
@@ -1938,7 +1951,7 @@ delete_node(Host, Node, Owner) ->
                        Error -> Error
                    end;
                _ ->
-                   {error, ?ERR_FORBIDDEN}
+                   {error, ?ERRT_FORBIDDEN(?MYLANG, <<"You're not an owner">>)}
            end
     end,
     Reply = [],
@@ -2247,22 +2260,28 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload, Access) ->
            {result, Reply};
        {result, {_, Result}} ->
            {result, Result};
-       {error, ?ERR_ITEM_NOT_FOUND} ->
-           Type = select_type(ServerHost, Host, Node),
-           case lists:member(<<"auto-create">>, plugin_features(Host, Type)) of
+       {error, _} = Error ->
+           case is_item_not_found(Error) of
                true ->
-                   case create_node(Host, ServerHost, Node, Publisher, Type, Access, []) of
-                       {result,
-                                   [#xmlel{name = <<"pubsub">>,
-                                           attrs = [{<<"xmlns">>, ?NS_PUBSUB}],
-                                           children = [#xmlel{name = <<"create">>,
-                                                   attrs = [{<<"node">>, NewNode}]}]}]} ->
-                           publish_item(Host, ServerHost, NewNode, Publisher, ItemId, Payload);
-                       _ ->
-                           {error, ?ERR_ITEM_NOT_FOUND}
+                   Type = select_type(ServerHost, Host, Node),
+                   case lists:member(<<"auto-create">>, plugin_features(Host, Type)) of
+                       true ->
+                           case create_node(Host, ServerHost, Node, Publisher, Type, Access, []) of
+                               {result,
+                                [#xmlel{name = <<"pubsub">>,
+                                        attrs = [{<<"xmlns">>, ?NS_PUBSUB}],
+                                        children = [#xmlel{name = <<"create">>,
+                                                           attrs = [{<<"node">>, NewNode}]}]}]} ->
+                                   publish_item(Host, ServerHost, NewNode, Publisher, ItemId, Payload);
+                               _ ->
+                                   {error, ?ERR_ITEM_NOT_FOUND}
+                           end;
+                       false ->
+                           Txt = <<"Automatic node creation is not enabled">>,
+                           {error, ?ERRT_ITEM_NOT_FOUND(?MYLANG, Txt)}
                    end;
                false ->
-                   {error, ?ERR_ITEM_NOT_FOUND}
+                   Error
            end;
        Error ->
            Error
@@ -2416,7 +2435,9 @@ get_items(Host, Node, From, SubId, SMaxItems, ItemIds, RSM) ->
            end;
        true ->
            case catch jlib:binary_to_integer(SMaxItems) of
-               {'EXIT', _} -> {error, ?ERR_BAD_REQUEST};
+               {'EXIT', _} ->
+                   Txt = <<"Value of 'max_items' should be integer">>,
+                   {error, ?ERRT_BAD_REQUEST(?MYLANG, Txt)};
                Val -> Val
            end
     end,
@@ -2639,7 +2660,7 @@ get_affiliations(Host, Node, JID) ->
                    {error,
                        extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, <<"modify-affiliations">>)};
                Affiliation /= owner ->
-                   {error, ?ERR_FORBIDDEN};
+                   {error, ?ERRT_FORBIDDEN(?MYLANG, <<"You're not an owner">>)};
                true ->
                    node_call(Host, Type, get_node_affiliations, [Nidx])
            end
@@ -2732,7 +2753,7 @@ set_affiliations(Host, Node, From, EntitiesEls) ->
                                FilteredEntities),
                            {result, []};
                        _ ->
-                           {error, ?ERR_FORBIDDEN}
+                           {error, ?ERRT_FORBIDDEN(?MYLANG, <<"You're not an owner">>)}
                    end
            end,
            case transaction(Host, Node, Action, sync_dirty) of
@@ -2948,7 +2969,7 @@ get_subscriptions(Host, Node, JID) ->
                    {error,
                        extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, <<"manage-subscriptions">>)};
                Affiliation /= owner ->
-                   {error, ?ERR_FORBIDDEN};
+                   {error, ?ERRT_FORBIDDEN(?MYLANG, <<"You're not an owner">>)};
                true ->
                    node_call(Host, Type, get_node_subscriptions, [Nidx])
            end
@@ -3059,10 +3080,10 @@ set_subscriptions(Host, Node, From, EntitiesEls) ->
                                    [], Entities),
                            case Result of
                                [] -> {result, []};
-                               _ -> {error, ?ERR_NOT_ACCEPTABLE}
+                               [{error, E}|_] -> {error, E}
                            end;
                        _ ->
-                           {error, ?ERR_FORBIDDEN}
+                           {error, ?ERRT_FORBIDDEN(?MYLANG, <<"You're not an owner">>)}
                    end
            end,
            case transaction(Host, Node, Action, sync_dirty) of
@@ -3606,7 +3627,7 @@ get_configure(Host, ServerHost, Node, From, Lang) ->
                                                children =
                                                get_configure_xfields(Type, Options, Lang, Groups)}]}]}]};
                _ ->
-                   {error, ?ERR_FORBIDDEN}
+                   {error, ?ERRT_FORBIDDEN(Lang, <<"You're not an owner">>)}
            end
     end,
     case transaction(Host, Node, Action, sync_dirty) of
@@ -3820,7 +3841,8 @@ set_configure(Host, Node, From, Els, Lang) ->
                                {result, owner} ->
                                    case jlib:parse_xdata_submit(XEl) of
                                        invalid ->
-                                           {error, ?ERR_BAD_REQUEST};
+                                           Txt = <<"Incorrect data form">>,
+                                           {error, ?ERRT_BAD_REQUEST(Lang, Txt)};
                                        XData ->
                                            OldOpts = case Options of
                                                [] -> node_options(Host, Type);
@@ -3840,7 +3862,8 @@ set_configure(Host, Node, From, Els, Lang) ->
                                            end
                                    end;
                                _ ->
-                                   {error, ?ERR_FORBIDDEN}
+                                   Txt = <<"You're not an owner">>,
+                                   {error, ?ERRT_FORBIDDEN(Lang, Txt)}
                            end
                    end,
                    case transaction(Host, Node, Action, transaction) of
@@ -3854,10 +3877,12 @@ set_configure(Host, Node, From, Els, Lang) ->
                            Other
                    end;
                _ ->
-                   {error, ?ERR_BAD_REQUEST}
+                   Txt = <<"Incorrect data form">>,
+                   {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
            end;
        _ ->
-           {error, ?ERR_BAD_REQUEST}
+           Txt = <<"No data form found">>,
+           {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
     end.
 
 add_opt(Key, Value, Opts) ->
@@ -3872,7 +3897,10 @@ add_opt(Key, Value, Opts) ->
        _ -> error
     end,
     case BoolVal of
-       error -> {error, ?ERR_NOT_ACCEPTABLE};
+       error ->
+           Txt = <<"Value of '~s' should be boolean">>,
+           ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
+           {error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)};
        _ -> set_xoption(Host, Opts, add_opt(Opt, BoolVal, NewOpts))
     end).
 
@@ -3885,10 +3913,14 @@ add_opt(Key, Value, Opts) ->
            if (Max =:= undefined) orelse (IVal =< Max) ->
                set_xoption(Host, Opts, add_opt(Opt, IVal, NewOpts));
               true ->
-               {error, ?ERR_NOT_ACCEPTABLE}
+               Txt = <<"Incorrect value of '~s'">>,
+               ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
+               {error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)}
            end;
        _ ->
-           {error, ?ERR_NOT_ACCEPTABLE}
+           Txt = <<"Value of '~s' should be integer">>,
+           ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
+           {error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)}
     end).
 
 -define(SET_ALIST_XOPT(Opt, Val, Vals),
@@ -3896,7 +3928,9 @@ add_opt(Key, Value, Opts) ->
        true ->
            set_xoption(Host, Opts, add_opt(Opt, jlib:binary_to_atom(Val), NewOpts));
        false ->
-           {error, ?ERR_NOT_ACCEPTABLE}
+           Txt = <<"Incorrect value of '~s'">>,
+           ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
+           {error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)}
     end).
 
 -define(SET_LIST_XOPT(Opt, Val),
@@ -4139,8 +4173,9 @@ features(Host, Node) when is_binary(Node) ->
 tree_call({_User, Server, _Resource}, Function, Args) ->
     tree_call(Server, Function, Args);
 tree_call(Host, Function, Args) ->
-    ?DEBUG("tree_call ~p ~p ~p", [Host, Function, Args]),
-    catch apply(tree(Host), Function, Args).
+    Tree = tree(Host),
+    ?DEBUG("tree_call apply(~s, ~s, ~p) @ ~s", [Tree, Function, Args, Host]),
+    catch apply(Tree, Function, Args).
 
 tree_action(Host, Function, Args) ->
     ?DEBUG("tree_action ~p ~p ~p", [Host, Function, Args]),
@@ -4267,6 +4302,13 @@ extended_error(#xmlel{name = Error, attrs = Attrs, children = SubEls}, Ext, ExtA
     #xmlel{name = Error, attrs = Attrs,
        children = lists:reverse([#xmlel{name = Ext, attrs = ExtAttrs} | SubEls])}.
 
+is_item_not_found({error, ErrEl}) ->
+    case fxml:get_subtag_with_xmlns(
+          ErrEl, <<"item-not-found">>, ?NS_STANZAS) of
+       #xmlel{} -> true;
+       _ -> false
+    end.
+
 string_to_ljid(JID) ->
     case jid:from_string(JID) of
        error ->
index 56c5f7205de6fea47c90c03f4080ddff470fbc1c..fee2a2284b35f4a5c238bdf6f09c3b53ed2bc388 100644 (file)
@@ -151,21 +151,28 @@ process_iq(From, To,
                                %% modules.  lists:foreach can
                                %% only return ok:
                                not_allowed ->
+                                   Txt = <<"Removal is not allowed">>,
                                    IQ#iq{type = error,
-                                         sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
+                                         sub_el = [SubEl,
+                                                   ?ERRT_NOT_ALLOWED(Lang, Txt)]};
                                not_exists ->
+                                   Txt = <<"No such user">>,
                                    IQ#iq{type = error,
                                          sub_el =
-                                             [SubEl, ?ERR_ITEM_NOT_FOUND]};
-                               _ ->
+                                             [SubEl,
+                                              ?ERRT_ITEM_NOT_FOUND(Lang, Txt)]};
+                               Err ->
+                                   ?ERROR_MSG("failed to remove user ~s@~s: ~p",
+                                              [User, Server, Err]),
                                    IQ#iq{type = error,
                                          sub_el =
                                              [SubEl,
                                               ?ERR_INTERNAL_SERVER_ERROR]}
                              end;
                          true ->
+                             Txt = <<"No password in this query">>,
                              IQ#iq{type = error,
-                                   sub_el = [SubEl, ?ERR_BAD_REQUEST]}
+                                   sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]}
                       end
                 end;
             (UTag == false) and (RTag /= false) and AllowRemove ->
@@ -182,7 +189,9 @@ process_iq(From, To,
                       ejabberd_auth:remove_user(User, Server),
                       ignore;
                   _ ->
-                      IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
+                      Txt = <<"The query is only allowed from local users">>,
+                      IQ#iq{type = error,
+                            sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}
                 end;
             (UTag /= false) and (PTag /= false) ->
                 User = fxml:get_tag_cdata(UTag),
@@ -200,11 +209,14 @@ process_iq(From, To,
                                                          SubEl, Source, Lang,
                                                          true);
                         _ ->
+                            Txt = <<"Incorrect data form">>,
                             IQ#iq{type = error,
-                                  sub_el = [SubEl, ?ERR_BAD_REQUEST]}
+                                  sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]}
                       end;
                   {error, malformed} ->
-                      IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]};
+                      Txt = <<"Incorrect CAPTCHA submit">>,
+                      IQ#iq{type = error,
+                            sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]};
                   _ ->
                       ErrText = <<"The CAPTCHA verification has failed">>,
                       IQ#iq{type = error,
@@ -344,7 +356,8 @@ try_register_or_set_password(User, Server, Password,
                      IQ#iq{type = error, sub_el = [SubEl, Error]}
                end;
            deny ->
-               IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]}
+               Txt = <<"Denied by ACL">>,
+               IQ#iq{type = error, sub_el = [SubEl, ?ERRT_FORBIDDEN(Lang, Txt)]}
          end;
       _ ->
          IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
@@ -359,13 +372,17 @@ try_set_password(User, Server, Password, IQ, SubEl,
              of
            ok -> IQ#iq{type = result, sub_el = []};
            {error, empty_password} ->
-               IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]};
+               Txt = <<"Empty password">>,
+               IQ#iq{type = error, sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]};
            {error, not_allowed} ->
-               IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
+               Txt = <<"Chaning password is not allowed">>,
+               IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
            {error, invalid_jid} ->
                IQ#iq{type = error,
-                     sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]};
-           _ ->
+                     sub_el = [SubEl, ?ERR_JID_MALFORMED]};
+           Err ->
+               ?ERROR_MSG("failed to register user ~s@~s: ~p",
+                          [User, Server, Err]),
                IQ#iq{type = error,
                      sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}
          end;
@@ -377,7 +394,7 @@ try_set_password(User, Server, Password, IQ, SubEl,
 
 try_register(User, Server, Password, SourceRaw, Lang) ->
     case jid:is_nodename(User) of
-      false -> {error, ?ERR_BAD_REQUEST};
+      false -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Malformed username">>)};
       _ ->
          JID = jid:make(User, Server, <<"">>),
          Access = gen_mod:get_module_opt(Server, ?MODULE, access,
@@ -387,8 +404,8 @@ try_register(User, Server, Password, SourceRaw, Lang) ->
          case {acl:match_rule(Server, Access, JID),
                check_ip_access(SourceRaw, IPAccess)}
              of
-           {deny, _} -> {error, ?ERR_FORBIDDEN};
-           {_, deny} -> {error, ?ERR_FORBIDDEN};
+           {deny, _} -> {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
+           {_, deny} -> {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
            {allow, allow} ->
                Source = may_remove_resource(SourceRaw),
                case check_timeout(Source) of
@@ -406,14 +423,20 @@ try_register(User, Server, Password, SourceRaw, Lang) ->
                              Error ->
                                  remove_timeout(Source),
                                  case Error of
-                                   {atomic, exists} -> {error, ?ERR_CONFLICT};
+                                   {atomic, exists} ->
+                                       Txt = <<"User already exists">>,
+                                       {error, ?ERRT_CONFLICT(Lang, Txt)};
                                    {error, invalid_jid} ->
                                        {error, ?ERR_JID_MALFORMED};
                                    {error, not_allowed} ->
                                        {error, ?ERR_NOT_ALLOWED};
                                    {error, too_many_users} ->
-                                       {error, ?ERR_NOT_ALLOWED};
-                                   {error, _Reason} ->
+                                       Txt = <<"Too many users registered">>,
+                                       {error, ?ERRT_RESOURCE_CONSTRAINT(Lang, Txt)};
+                                   {error, _} ->
+                                       ?ERROR_MSG("failed to register user "
+                                                  "~s@~s: ~p",
+                                                  [User, Server, Error]),
                                        {error, ?ERR_INTERNAL_SERVER_ERROR}
                                  end
                            end;
index 5aeb973d123d4309e42fc8bb0e1ee1028eea6ea8..5dd52066889b2b6a021aa6608e8cb679d308735a 100644 (file)
@@ -800,8 +800,10 @@ get_item(Nidx, ItemId) ->
        {selected,
                    [<<"itemid">>, <<"publisher">>, <<"creation">>, <<"modification">>, <<"payload">>], [RItem]} ->
            {result, raw_to_item(Nidx, RItem)};
-       _ ->
-           {error, ?ERR_ITEM_NOT_FOUND}
+       {selected, _, []} ->
+           {error, ?ERR_ITEM_NOT_FOUND};
+       {'EXIT', _} ->
+           {error, ?ERRT_INTERNAL_SERVER_ERROR(?MYLANG, <<"Database failure">>)}
     end.
 
 get_item(Nidx, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId) ->