1
0
Fork 0
mirror of https://github.com/processone/ejabberd synced 2025-10-03 01:39:35 +02:00

Compare commits

...

2 commits

Author SHA1 Message Date
Pawel Chmielowski
1a9b147baf Report db failures in mod_muc_mnesia:restore_room 2025-07-23 20:27:19 +02:00
Pawel Chmielowski
6214e0385d Report db failures from mod_muc:restore_room 2025-07-23 19:59:32 +02:00
4 changed files with 43 additions and 14 deletions

View file

@ -97,7 +97,7 @@
-callback import(binary(), binary(), [binary()]) -> ok.
-callback store_room(binary(), binary(), binary(), list(), list()|undefined) -> {atomic, any()}.
-callback store_changes(binary(), binary(), binary(), list()) -> {atomic, any()}.
-callback restore_room(binary(), binary(), binary()) -> muc_room_opts() | error.
-callback restore_room(binary(), binary(), binary()) -> muc_room_opts() | error | {error, atom()}.
-callback forget_room(binary(), binary(), binary()) -> {atomic, any()}.
-callback can_use_nick(binary(), binary(), jid(), binary()) -> boolean().
-callback get_rooms(binary(), binary()) -> [#muc_room{}].
@ -591,20 +591,17 @@ extract_password(#iq{} = IQ) ->
false
end.
-spec unhibernate_room(binary(), binary(), binary()) -> {ok, pid()} | error.
-spec unhibernate_room(binary(), binary(), binary()) -> {ok, pid()} | {error, notfound | db_failure | term()}.
unhibernate_room(ServerHost, Host, Room) ->
unhibernate_room(ServerHost, Host, Room, true).
-spec unhibernate_room(binary(), binary(), binary(), boolean()) -> {ok, pid()} | error.
-spec unhibernate_room(binary(), binary(), binary(), boolean()) -> {ok, pid()} | {error, notfound | db_failure | term()}.
unhibernate_room(ServerHost, Host, Room, ResetHibernationTime) ->
RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE),
case RMod:find_online_room(ServerHost, Room, Host) of
error ->
Proc = procname(ServerHost, {Room, Host}),
case ?GEN_SERVER:call(Proc, {unhibernate, Room, Host, ResetHibernationTime}, 20000) of
{ok, _} = R -> R;
_ -> error
end;
?GEN_SERVER:call(Proc, {unhibernate, Room, Host, ResetHibernationTime}, 20000);
{ok, _} = R2 -> R2
end.
@ -888,6 +885,8 @@ load_room(RMod, Host, ServerHost, Room, ResetHibernationTime) ->
case restore_room(ServerHost, Host, Room) of
error ->
{error, notfound};
{error, _} = Err ->
Err;
Opts0 ->
Mod = gen_mod:db_mod(ServerHost, mod_muc),
case proplists:get_bool(persistent, Opts0) of

View file

@ -1289,6 +1289,8 @@ create_room_with_opts(Name1, Host1, ServerHost1, CustomRoomOpts) ->
{error, _} ->
throw({error, "Unable to start room"})
end;
{db_failure, _Name, _Host} ->
throw({error, "Database error"});
_ ->
throw({error, "Room already exists"})
end.
@ -1307,6 +1309,8 @@ destroy_room(Name1, Service1) ->
case get_room_pid_validate(Name1, Service1, <<"service">>) of
{room_not_found, _, _} ->
throw({error, "Room doesn't exists"});
{db_failure, _Name, _Host} ->
throw({error, "Database error"});
{Pid, _, _} ->
mod_muc_room:destroy(Pid),
ok
@ -1698,6 +1702,8 @@ change_room_option(Name, Service, OptionString, ValueString) ->
case get_room_pid_validate(Name, Service, <<"service">>) of
{room_not_found, _, _} ->
throw({error, "Room not found"});
{db_failure, _Name, _Host} ->
throw({error, "Database error"});
{Pid, _, _} ->
{Option, Value} = format_room_option(OptionString, ValueString),
change_room_option(Pid, Option, Value)
@ -1823,25 +1829,29 @@ parse_nodes(_, _) ->
throw({error, "Invalid 'subscribers' - unknown node name used"}).
-spec get_room_pid_validate(binary(), binary(), binary()) ->
{pid() | room_not_found, binary(), binary()}.
{pid() | room_not_found | db_failure, binary(), binary()}.
get_room_pid_validate(Name, Service, ServiceArg) ->
Name2 = validate_room(Name),
{ServerHost, Service2} = validate_muc2(Service, ServiceArg),
case mod_muc:unhibernate_room(ServerHost, Service2, Name2) of
error ->
{error, notfound} ->
{room_not_found, Name2, Service2};
{error, db_failure} ->
{db_failure, Name2, Service2};
{ok, Pid} ->
{Pid, Name2, Service2}
end.
%% @doc Get the Pid of an existing MUC room, or 'room_not_found'.
-spec get_room_pid(binary(), binary()) -> pid() | room_not_found | invalid_service | unknown_service.
-spec get_room_pid(binary(), binary()) -> pid() | room_not_found | db_failure | invalid_service | unknown_service.
get_room_pid(Name, Service) ->
try get_room_serverhost(Service) of
ServerHost ->
case mod_muc:unhibernate_room(ServerHost, Service, Name) of
error ->
{error, notfound} ->
room_not_found;
{error, db_failure} ->
db_failure;
{ok, Pid} ->
Pid
end
@ -1954,6 +1964,8 @@ get_room_affiliations(Name, Service) ->
({{Uname, Domain, _Res}, Aff}) when is_atom(Aff)->
{Uname, Domain, Aff, <<>>}
end, Affiliations);
{db_failure, _Name, _Host} ->
throw({error, "Database error"});
_ ->
throw({error, "The room does not exist."})
end.
@ -1975,6 +1987,8 @@ get_room_affiliations_v3(Name, Service) ->
Jid = makeencode(Uname, Domain),
{Jid, Aff, <<>>}
end, Affiliations);
{db_failure, _Name, _Host} ->
throw({error, "Database error"});
_ ->
throw({error, "The room does not exist."})
end.
@ -1993,6 +2007,8 @@ get_room_history(Name, Service) ->
_ ->
throw({error, "Unable to fetch room state."})
end;
{db_failure, _Name, _Host} ->
throw({error, "Database error"});
_ ->
throw({error, "The room does not exist."})
end.
@ -2012,6 +2028,8 @@ get_room_affiliation(Name, Service, JID) ->
{ok, StateData} = mod_muc_room:get_state(Pid),
UserJID = jid:decode(JID),
mod_muc_room:get_affiliation(UserJID, StateData);
{db_failure, _Name, _Host} ->
throw({error, "Database error"});
_ ->
throw({error, "The room does not exist."})
end.
@ -2052,6 +2070,8 @@ set_room_affiliation(Name, Service, JID, AffiliationString) ->
{error, _} ->
throw({error, "Unable to perform change"})
end;
{db_failure, _Name, _Host} ->
throw({error, "Database error"});
_ ->
throw({error, "Room doesn't exists"})
end.
@ -2084,6 +2104,8 @@ subscribe_room(User, Nick, Room, NodeList) ->
{error, Reason} ->
throw({error, binary_to_list(Reason)})
end;
{db_failure, _Name, _Host} ->
throw({error, "Database error"});
_ ->
throw({error, "The room does not exist"})
end
@ -2129,6 +2151,8 @@ unsubscribe_room(User, Room) ->
{error, Reason} ->
throw({error, binary_to_list(Reason)})
end;
{db_failure, _Name, _Host} ->
throw({error, "Database error"});
_ ->
throw({error, "The room does not exist"})
end
@ -2146,6 +2170,8 @@ get_subscribers(Name, Host) ->
{Pid, _, _} when is_pid(Pid) ->
{ok, JIDList} = mod_muc_room:get_subscribers(Pid),
[jid:encode(jid:remove_resource(J)) || J <- JIDList];
{db_failure, _Name, _Host} ->
throw({error, "Database error"});
_ ->
throw({error, "The room does not exist"})
end.

View file

@ -76,9 +76,11 @@ store_room(_LServer, Host, Name, Opts, _) ->
mnesia:transaction(F).
restore_room(_LServer, Host, Name) ->
case catch mnesia:dirty_read(muc_room, {Name, Host}) of
try mnesia:dirty_read(muc_room, {Name, Host}) of
[#muc_room{opts = Opts}] -> Opts;
_ -> error
catch
_:_ -> {error, db_failure}
end.
forget_room(_LServer, Host, Name) ->

View file

@ -220,10 +220,12 @@ restore_room(LServer, Host, Name) ->
Opts2 = lists:keystore(subscribers, 1, OptsD, {subscribers, SubData}),
mod_muc:opts_to_binary(Opts2);
_ ->
error
{error, db_failure}
end;
{selected, _} ->
error;
_ ->
error
{error, db_failure}
end.
forget_room(LServer, Host, Name) ->