diff --git a/.github/container/Dockerfile b/.github/container/Dockerfile
index b1c5aa5d1..1d238339a 100644
--- a/.github/container/Dockerfile
+++ b/.github/container/Dockerfile
@@ -1,5 +1,5 @@
#' Define default build variables
-ARG OTP_VSN='27.3.4.2'
+ARG OTP_VSN='27.3.4.3'
ARG ELIXIR_VSN='1.18.4'
ARG UID='9000'
ARG USER='ejabberd'
diff --git a/CONTAINER.md b/CONTAINER.md
index b17d4fb40..e96081112 100644
--- a/CONTAINER.md
+++ b/CONTAINER.md
@@ -1072,7 +1072,7 @@ Let's summarize the differences between both container images. Legend:
| Generated by | [container.yml](https://github.com/processone/ejabberd/blob/master/.github/workflows/container.yml) | [tests.yml](https://github.com/processone/docker-ejabberd/blob/master/.github/workflows/tests.yml) |
| Built for | stable releases
`master` branch | stable releases
[`master` branch zip](https://github.com/processone/docker-ejabberd/actions/workflows/tests.yml) |
| Architectures | `linux/amd64`
`linux/arm64` | `linux/amd64` |
-| Software | Erlang/OTP 27.3.4.2-alpine
Elixir 1.18.4 | Alpine 3.19
Erlang/OTP 26.2
Elixir 1.15.7 |
+| Software | Erlang/OTP 27.3.4.3-alpine
Elixir 1.18.4 | Alpine 3.22
Erlang/OTP 26.2
Elixir 1.18.3 |
| Published in | [ghcr.io/processone/ejabberd](https://github.com/processone/ejabberd/pkgs/container/ejabberd) | [docker.io/ejabberd/ecs](https://hub.docker.com/r/ejabberd/ecs/)
[ghcr.io/processone/ecs](https://github.com/processone/docker-ejabberd/pkgs/container/ecs) |
| :black_square_button: **Additional content** |
| [ejabberd-contrib](#ejabberd-contrib) | included | not included |
diff --git a/ejabberdctl.template b/ejabberdctl.template
index 58a0d8be6..0d124bead 100755
--- a/ejabberdctl.template
+++ b/ejabberdctl.template
@@ -553,7 +553,8 @@ case $1 in
-noinput -hidden \
-eval 'net_kernel:connect_node('"'$PEER'"')' \
-eval 'io:format("~p~n",[net_adm:ping('"'$PEER'"')])' \
- -s erlang halt -output text
+ -eval 'halt(case net_adm:ping('"'$PEER'"') of pong -> 0; pang -> 1 end).' \
+ -output text
;;
started)
set_dist_client
diff --git a/include/ejabberd_stacktrace.hrl b/include/ejabberd_stacktrace.hrl
deleted file mode 100644
index e65c5264f..000000000
--- a/include/ejabberd_stacktrace.hrl
+++ /dev/null
@@ -1,27 +0,0 @@
-%%%----------------------------------------------------------------------
-%%%
-%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License along
-%%% with this program; if not, write to the Free Software Foundation, Inc.,
-%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-%%%
-%%%----------------------------------------------------------------------
-
--ifdef(DEPRECATED_GET_STACKTRACE).
--define(EX_RULE(Class, Reason, Stack), Class:Reason:Stack).
--define(EX_STACK(Stack), Stack).
--else.
--define(EX_RULE(Class, Reason, _), Class:Reason).
--define(EX_STACK(_), erlang:get_stacktrace()).
--endif.
diff --git a/mix.exs b/mix.exs
index c5600b228..5b5be84f5 100644
--- a/mix.exs
+++ b/mix.exs
@@ -85,7 +85,6 @@ defmodule Ejabberd.MixProject do
result = [{:d, :ELIXIR_ENABLED}] ++
cond_options() ++
Enum.map(includes, fn (path) -> {:i, path} end) ++
- if_version_above(~c"20", [{:d, :DEPRECATED_GET_STACKTRACE}]) ++
if_version_above(~c"20", [{:d, :HAVE_URI_STRING}]) ++
if_version_above(~c"20", [{:d, :HAVE_ERL_ERROR}]) ++
if_version_below(~c"21", [{:d, :USE_OLD_HTTP_URI}]) ++
diff --git a/rebar.config b/rebar.config
index e3d42edce..1d0f9a8db 100644
--- a/rebar.config
+++ b/rebar.config
@@ -126,7 +126,6 @@
{erl_opts, [nowarn_deprecated_function,
{i, "include"},
- {if_version_above, "20", {d, 'DEPRECATED_GET_STACKTRACE'}},
{if_version_above, "20", {d, 'HAVE_ERL_ERROR'}},
{if_version_above, "20", {d, 'HAVE_URI_STRING'}},
{if_version_below, "21", {d, 'USE_OLD_HTTP_URI'}},
diff --git a/src/ejabberd_app.erl b/src/ejabberd_app.erl
index a31d7b1a6..cbe74fb08 100644
--- a/src/ejabberd_app.erl
+++ b/src/ejabberd_app.erl
@@ -32,7 +32,7 @@
-export([start/2, prep_stop/1, stop/1]).
-include("logger.hrl").
--include("ejabberd_stacktrace.hrl").
+
%%%
%%% Application API
diff --git a/src/ejabberd_config.erl b/src/ejabberd_config.erl
index 8c10041e5..11173f9e8 100644
--- a/src/ejabberd_config.erl
+++ b/src/ejabberd_config.erl
@@ -52,7 +52,7 @@
{get_lang, 1}]).
-include("logger.hrl").
--include("ejabberd_stacktrace.hrl").
+
-type option() :: atom() | {atom(), global | binary()}.
-type error_reason() :: {merge_conflict, atom(), binary()} |
@@ -169,14 +169,14 @@ get_option({O, Host} = Opt) ->
T -> T
end,
try ets:lookup_element(Tab, Opt, 2)
- catch ?EX_RULE(error, badarg, St) when Host /= global ->
- StackTrace = ?EX_STACK(St),
- Val = get_option({O, global}),
- ?DEBUG("Option '~ts' is not defined for virtual host '~ts'. "
- "This is a bug, please report it with the following "
- "stacktrace included:~n** ~ts",
- [O, Host, misc:format_exception(2, error, badarg, StackTrace)]),
- Val
+ catch
+ error:badarg:StackTrace when Host /= global ->
+ Val = get_option({O, global}),
+ ?DEBUG("Option '~ts' is not defined for virtual host '~ts'. "
+ "This is a bug, please report it with the following "
+ "stacktrace included:~n** ~ts",
+ [O, Host, misc:format_exception(2, error, badarg, StackTrace)]),
+ Val
end.
-spec set_option(option(), term()) -> ok.
@@ -802,8 +802,9 @@ load_file(File) ->
Err ->
abort(Err)
end
- catch ?EX_RULE(Class, Reason, St) ->
- {error, {exception, Class, Reason, ?EX_STACK(St)}}
+ catch
+ Class:Reason:Stack ->
+ {error, {exception, Class, Reason, Stack}}
end.
-spec commit() -> ok.
diff --git a/src/ejabberd_ctl.erl b/src/ejabberd_ctl.erl
index 88bd5e785..075854e40 100644
--- a/src/ejabberd_ctl.erl
+++ b/src/ejabberd_ctl.erl
@@ -39,7 +39,7 @@
-include("ejabberd_commands.hrl").
-include("ejabberd_http.hrl").
-include("logger.hrl").
--include("ejabberd_stacktrace.hrl").
+
-define(DEFAULT_VERSION, 1000000).
@@ -331,11 +331,10 @@ try_call_command(Args, Auth, AccessCommands, Version) ->
?STATUS_ERROR};
throw:Error ->
{io_lib:format("~p", [Error]), ?STATUS_ERROR};
- ?EX_RULE(A, Why, Stack) ->
- StackTrace = ?EX_STACK(Stack),
- {io_lib:format("Unhandled exception occurred executing the command:~n** ~ts",
- [misc:format_exception(2, A, Why, StackTrace)]),
- ?STATUS_ERROR}
+ A:Why:StackTrace ->
+ {io_lib:format("Unhandled exception occurred executing the command:~n** ~ts",
+ [misc:format_exception(2, A, Why, StackTrace)]),
+ ?STATUS_ERROR}
end.
-spec call_command(Args::[string()],
diff --git a/src/ejabberd_hooks.erl b/src/ejabberd_hooks.erl
index 0fedc1dfc..8f378aa48 100644
--- a/src/ejabberd_hooks.erl
+++ b/src/ejabberd_hooks.erl
@@ -60,7 +60,7 @@
).
-include("logger.hrl").
--include("ejabberd_stacktrace.hrl").
+
-record(state, {}).
-type subscriber() :: {Module :: atom(), Function :: atom(), InitArg :: any()}.
@@ -455,17 +455,19 @@ safe_apply(Hook, Module, Function, Args) ->
true ->
apply(Module, Function, Args)
end
- catch ?EX_RULE(E, R, St) when E /= exit; R /= normal ->
- Stack = ?EX_STACK(St),
- ?ERROR_MSG("Hook ~p crashed when running ~p:~p/~p:~n" ++
- string:join(
- ["** ~ts"|
- ["** Arg " ++ integer_to_list(I) ++ " = ~p"
- || I <- lists:seq(1, length(Args))]],
- "~n"),
- [Hook, Module, Function, length(Args),
- misc:format_exception(2, E, R, Stack)|Args]),
- 'EXIT'
+ catch
+ E:R:Stack when E /= exit; R /= normal ->
+ ?ERROR_MSG("Hook ~p crashed when running ~p:~p/~p:~n" ++
+ string:join(
+ ["** ~ts" | [ "** Arg " ++ integer_to_list(I) ++ " = ~p"
+ || I <- lists:seq(1, length(Args)) ]],
+ "~n"),
+ [Hook,
+ Module,
+ Function,
+ length(Args),
+ misc:format_exception(2, E, R, Stack) | Args]),
+ 'EXIT'
end.
-spec call_subscriber_list([subscriber()], binary() | global, atom(), {atom(), atom(), integer(), list()} | list(), subscriber_event(), [subscriber()]) -> any().
@@ -480,18 +482,20 @@ call_subscriber_list([{Mod, Func, InitArg} | SubscriberList], Host, Hook, Callba
try apply(Mod, Func, SubscriberArgs) of
State ->
call_subscriber_list(SubscriberList, Host, Hook, CallbackOrArgs, Event, [{Mod, Func, State} | Result])
- catch ?EX_RULE(E, R, St) when E /= exit; R /= normal ->
- Stack = ?EX_STACK(St),
- ?ERROR_MSG("Hook subscriber ~p crashed when running ~p:~p/~p:~n" ++
- string:join(
- ["** ~ts"|
- ["** Arg " ++ integer_to_list(I) ++ " = ~p"
- || I <- lists:seq(1, length(SubscriberArgs))]],
- "~n"),
- [Hook, Mod, Func, length(SubscriberArgs),
- misc:format_exception(2, E, R, Stack)|SubscriberArgs]),
- %% Do not append subscriber for next calls:
- call_subscriber_list(SubscriberList, Host, Hook, CallbackOrArgs, Event, Result)
+ catch
+ E:R:Stack when E /= exit; R /= normal ->
+ ?ERROR_MSG("Hook subscriber ~p crashed when running ~p:~p/~p:~n" ++
+ string:join(
+ ["** ~ts" | [ "** Arg " ++ integer_to_list(I) ++ " = ~p"
+ || I <- lists:seq(1, length(SubscriberArgs)) ]],
+ "~n"),
+ [Hook,
+ Mod,
+ Func,
+ length(SubscriberArgs),
+ misc:format_exception(2, E, R, Stack) | SubscriberArgs]),
+ %% Do not append subscriber for next calls:
+ call_subscriber_list(SubscriberList, Host, Hook, CallbackOrArgs, Event, Result)
end.
%%%----------------------------------------------------------------------
@@ -709,13 +713,11 @@ run_event_handlers(TracingOpts, Hook, Host, Event, EventArgs, RunType) ->
_ ->
ok
catch
- ?EX_RULE(E, R, St) ->
- Stack = ?EX_STACK(St),
- ?ERROR_MSG(
+ E:R:Stack ->
+ ?ERROR_MSG(
"(~0p|~ts|~0p) Tracing event '~0p' handler exception(~0p): ~0p: ~0p",
- [Hook, Host, erlang:self(), EventHandler, E, R, Stack]
- ),
- ok
+ [Hook, Host, erlang:self(), EventHandler, E, R, Stack]),
+ ok
end
end,
EventHandlerList
@@ -885,8 +887,7 @@ tracing_output(#{output_function := OutputF}, Text, Args) ->
_ ->
ok
catch
- ?EX_RULE(E, R, St) ->
- Stack = ?EX_STACK(St),
+ E:R:Stack ->
?ERROR_MSG("Tracing output function exception(~0p): ~0p: ~0p", [E, R, Stack]),
ok
end;
diff --git a/src/ejabberd_http.erl b/src/ejabberd_http.erl
index b8e05dec4..709585145 100644
--- a/src/ejabberd_http.erl
+++ b/src/ejabberd_http.erl
@@ -39,7 +39,7 @@
-include("logger.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("ejabberd_http.hrl").
--include("ejabberd_stacktrace.hrl").
+
-include_lib("kernel/include/file.hrl").
-record(state, {sockmod,
@@ -372,11 +372,11 @@ process(Handlers, Request) ->
try
HandlerModule:process(LocalPath, Request)
catch
- ?EX_RULE(Class, Reason, Stack) ->
+ Class:Reason:Stack ->
?ERROR_MSG(
- "HTTP handler crashed: ~s",
- [misc:format_exception(2, Class, Reason, ?EX_STACK(Stack))]),
- erlang:raise(Class, Reason, ?EX_STACK(Stack))
+ "HTTP handler crashed: ~s",
+ [misc:format_exception(2, Class, Reason, Stack)]),
+ erlang:raise(Class, Reason, Stack)
end
end,
ejabberd_hooks:run(http_request_debug, [{LocalPath, Request}]),
diff --git a/src/ejabberd_iq.erl b/src/ejabberd_iq.erl
index 507820b20..5db539cab 100644
--- a/src/ejabberd_iq.erl
+++ b/src/ejabberd_iq.erl
@@ -36,7 +36,7 @@
-include_lib("xmpp/include/xmpp.hrl").
-include("logger.hrl").
--include("ejabberd_stacktrace.hrl").
+
-record(state, {expire = infinity :: timeout()}).
-type state() :: #state{}.
@@ -174,11 +174,11 @@ calc_checksum(Data) ->
-spec callback(atom() | pid(), #iq{} | timeout, term()) -> any().
callback(undefined, IQRes, Fun) ->
try Fun(IQRes)
- catch ?EX_RULE(Class, Reason, St) ->
- StackTrace = ?EX_STACK(St),
- ?ERROR_MSG("Failed to process iq response:~n~ts~n** ~ts",
- [xmpp:pp(IQRes),
- misc:format_exception(2, Class, Reason, StackTrace)])
+ catch
+ Class:Reason:StackTrace ->
+ ?ERROR_MSG("Failed to process iq response:~n~ts~n** ~ts",
+ [xmpp:pp(IQRes),
+ misc:format_exception(2, Class, Reason, StackTrace)])
end;
callback(Proc, IQRes, Ctx) ->
try
diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl
index 34735cd2c..5d9557415 100644
--- a/src/ejabberd_local.erl
+++ b/src/ejabberd_local.erl
@@ -48,7 +48,7 @@
-include("logger.hrl").
-include_lib("stdlib/include/ms_transform.hrl").
-include_lib("xmpp/include/xmpp.hrl").
--include("ejabberd_stacktrace.hrl").
+
-include("translate.hrl").
-record(state, {}).
diff --git a/src/ejabberd_mnesia.erl b/src/ejabberd_mnesia.erl
index 5b82dbb50..d9db27219 100644
--- a/src/ejabberd_mnesia.erl
+++ b/src/ejabberd_mnesia.erl
@@ -42,7 +42,7 @@
-define(NEED_RESET, [local_content, type]).
-include("logger.hrl").
--include("ejabberd_stacktrace.hrl").
+
-record(state, {tables = #{} :: tables(),
schema = [] :: [{atom(), custom_schema()}]}).
@@ -377,14 +377,15 @@ do_transform(OldAttrs, Attrs, Old) ->
transform_fun(Module, Name) ->
fun(Obj) ->
try Module:transform(Obj)
- catch ?EX_RULE(Class, Reason, St) ->
- StackTrace = ?EX_STACK(St),
- ?ERROR_MSG("Failed to transform Mnesia table ~ts:~n"
- "** Record: ~p~n"
- "** ~ts",
- [Name, Obj,
- misc:format_exception(2, Class, Reason, StackTrace)]),
- erlang:raise(Class, Reason, StackTrace)
+ catch
+ Class:Reason:StackTrace ->
+ ?ERROR_MSG("Failed to transform Mnesia table ~ts:~n"
+ "** Record: ~p~n"
+ "** ~ts",
+ [Name,
+ Obj,
+ misc:format_exception(2, Class, Reason, StackTrace)]),
+ erlang:raise(Class, Reason, StackTrace)
end
end.
diff --git a/src/ejabberd_redis.erl b/src/ejabberd_redis.erl
index 27e8775e1..c0e61c0e6 100644
--- a/src/ejabberd_redis.erl
+++ b/src/ejabberd_redis.erl
@@ -48,7 +48,7 @@
-define(CALL_TIMEOUT, 60*1000). %% 60 seconds
-include("logger.hrl").
--include("ejabberd_stacktrace.hrl").
+
-record(state, {connection :: pid() | undefined,
num :: pos_integer(),
@@ -114,9 +114,10 @@ multi(F) ->
{error, _} = Err -> Err;
Result -> get_result(Result)
end
- catch ?EX_RULE(E, R, St) ->
- erlang:erase(?TR_STACK),
- erlang:raise(E, R, ?EX_STACK(St))
+ catch
+ E:R:St ->
+ erlang:erase(?TR_STACK),
+ erlang:raise(E, R, St)
end;
_ ->
erlang:error(nested_transaction)
diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl
index de088d8ba..236b5081a 100644
--- a/src/ejabberd_router.erl
+++ b/src/ejabberd_router.erl
@@ -70,7 +70,8 @@
-include("logger.hrl").
-include("ejabberd_router.hrl").
-include_lib("xmpp/include/xmpp.hrl").
--include("ejabberd_stacktrace.hrl").
+
+
-callback init() -> any().
-callback register_route(binary(), binary(), local_hint(),
@@ -90,11 +91,11 @@ start_link() ->
-spec route(stanza()) -> ok.
route(Packet) ->
try do_route(Packet)
- catch ?EX_RULE(Class, Reason, St) ->
- StackTrace = ?EX_STACK(St),
- ?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts",
- [xmpp:pp(Packet),
- misc:format_exception(2, Class, Reason, StackTrace)])
+ catch
+ Class:Reason:StackTrace ->
+ ?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts",
+ [xmpp:pp(Packet),
+ misc:format_exception(2, Class, Reason, StackTrace)])
end.
-spec route(jid(), jid(), xmlel() | stanza()) -> ok.
diff --git a/src/ejabberd_router_sql.erl b/src/ejabberd_router_sql.erl
index ad120d82f..2d7631476 100644
--- a/src/ejabberd_router_sql.erl
+++ b/src/ejabberd_router_sql.erl
@@ -32,7 +32,8 @@
-include("logger.hrl").
-include("ejabberd_sql_pt.hrl").
-include("ejabberd_router.hrl").
--include("ejabberd_stacktrace.hrl").
+
+
%%%===================================================================
%%% API
@@ -141,13 +142,13 @@ row_to_route(Domain, {ServerHost, NodeS, PidS, LocalHintS} = Row) ->
local_hint = dec_local_hint(LocalHintS)}]
catch _:{bad_node, _} ->
[];
- ?EX_RULE(Class, Reason, St) ->
- StackTrace = ?EX_STACK(St),
- ?ERROR_MSG("Failed to decode row from 'route' table:~n"
- "** Row = ~p~n"
- "** Domain = ~ts~n"
- "** ~ts",
- [Row, Domain,
- misc:format_exception(2, Class, Reason, StackTrace)]),
- []
+ Class:Reason:StackTrace ->
+ ?ERROR_MSG("Failed to decode row from 'route' table:~n"
+ "** Row = ~p~n"
+ "** Domain = ~ts~n"
+ "** ~ts",
+ [Row,
+ Domain,
+ misc:format_exception(2, Class, Reason, StackTrace)]),
+ []
end.
diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl
index 448773612..0876ca584 100644
--- a/src/ejabberd_s2s.erl
+++ b/src/ejabberd_s2s.erl
@@ -53,7 +53,7 @@
-include_lib("xmpp/include/xmpp.hrl").
-include("ejabberd_commands.hrl").
-include_lib("stdlib/include/ms_transform.hrl").
--include("ejabberd_stacktrace.hrl").
+
-include("translate.hrl").
-define(DEFAULT_MAX_S2S_CONNECTIONS_NUMBER, 1).
@@ -249,11 +249,11 @@ handle_info({mnesia_system_event, {mnesia_up, Node}}, State) ->
{noreply, State};
handle_info({route, Packet}, State) ->
try route(Packet)
- catch ?EX_RULE(Class, Reason, St) ->
- StackTrace = ?EX_STACK(St),
- ?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts",
- [xmpp:pp(Packet),
- misc:format_exception(2, Class, Reason, StackTrace)])
+ catch
+ Class:Reason:StackTrace ->
+ ?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts",
+ [xmpp:pp(Packet),
+ misc:format_exception(2, Class, Reason, StackTrace)])
end,
{noreply, State};
handle_info({'DOWN', _Ref, process, Pid, _Reason}, State) ->
diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl
index 296452736..d6d81fbbe 100644
--- a/src/ejabberd_sm.erl
+++ b/src/ejabberd_sm.erl
@@ -92,7 +92,7 @@
-include_lib("xmpp/include/xmpp.hrl").
-include("ejabberd_commands.hrl").
-include("ejabberd_sm.hrl").
--include("ejabberd_stacktrace.hrl").
+
-include("translate.hrl").
-callback init() -> ok | {error, any()}.
@@ -131,13 +131,14 @@ stop() ->
%% @doc route arbitrary term to c2s process(es)
route(To, Term) ->
try do_route(To, Term), ok
- catch ?EX_RULE(E, R, St) ->
- StackTrace = ?EX_STACK(St),
- ?ERROR_MSG("Failed to route term to ~ts:~n"
- "** Term = ~p~n"
- "** ~ts",
- [jid:encode(To), Term,
- misc:format_exception(2, E, R, StackTrace)])
+ catch
+ E:R:StackTrace ->
+ ?ERROR_MSG("Failed to route term to ~ts:~n"
+ "** Term = ~p~n"
+ "** ~ts",
+ [jid:encode(To),
+ Term,
+ misc:format_exception(2, E, R, StackTrace)])
end.
-spec route(stanza()) -> ok.
diff --git a/src/ejabberd_sql.erl b/src/ejabberd_sql.erl
index 0c29f039e..922fec14a 100644
--- a/src/ejabberd_sql.erl
+++ b/src/ejabberd_sql.erl
@@ -89,7 +89,7 @@
-include("logger.hrl").
-include("ejabberd_sql_pt.hrl").
--include("ejabberd_stacktrace.hrl").
+
-record(state,
{db_ref :: undefined | db_ref_pid() | odbc_connection_reference(),
@@ -616,19 +616,20 @@ outer_transaction(F, NRestarts, _Reason) ->
{atomic, Res}
end
catch
- ?EX_RULE(throw, {aborted, Reason}, _) when NRestarts > 0 ->
- maybe_restart_transaction(F, NRestarts, Reason, true);
- ?EX_RULE(throw, {aborted, Reason}, Stack) when NRestarts =:= 0 ->
- StackTrace = ?EX_STACK(Stack),
- ?ERROR_MSG("SQL transaction restarts exceeded~n** "
- "Restarts: ~p~n** Last abort reason: "
- "~p~n** Stacktrace: ~p~n** When State "
- "== ~p",
- [?MAX_TRANSACTION_RESTARTS, Reason,
- StackTrace, get(?STATE_KEY)]),
- maybe_restart_transaction(F, NRestarts, Reason, true);
- ?EX_RULE(_, Reason, _) ->
- maybe_restart_transaction(F, 0, Reason, true)
+ throw:{aborted, Reason}:_ when NRestarts > 0 ->
+ maybe_restart_transaction(F, NRestarts, Reason, true);
+ throw:{aborted, Reason}:StackTrace when NRestarts =:= 0 ->
+ ?ERROR_MSG("SQL transaction restarts exceeded~n** "
+ "Restarts: ~p~n** Last abort reason: "
+ "~p~n** Stacktrace: ~p~n** When State "
+ "== ~p",
+ [?MAX_TRANSACTION_RESTARTS,
+ Reason,
+ StackTrace,
+ get(?STATE_KEY)]),
+ maybe_restart_transaction(F, NRestarts, Reason, true);
+ _:Reason:_ ->
+ maybe_restart_transaction(F, 0, Reason, true)
end
end.
@@ -742,10 +743,9 @@ sql_query_internal(#sql_query{} = Query) ->
{error, <<"terminated unexpectedly">>};
exit:{shutdown, _} ->
{error, <<"shutdown">>};
- ?EX_RULE(Class, Reason, Stack) ->
- StackTrace = ?EX_STACK(Stack),
+ Class:Reason:StackTrace ->
?ERROR_MSG("Internal error while processing SQL query:~n** ~ts",
- [misc:format_exception(2, Class, Reason, StackTrace)]),
+ [misc:format_exception(2, Class, Reason, StackTrace)]),
{error, <<"internal error">>}
end,
check_error(Res, Query);
@@ -935,12 +935,11 @@ sql_query_format_res({selected, _, Rows}, SQLQuery) ->
try
[(SQLQuery#sql_query.format_res)(Row)]
catch
- ?EX_RULE(Class, Reason, Stack) ->
- StackTrace = ?EX_STACK(Stack),
+ Class:Reason:StackTrace ->
?ERROR_MSG("Error while processing SQL query result:~n"
"** Row: ~p~n** ~ts",
[Row,
- misc:format_exception(2, Class, Reason, StackTrace)]),
+ misc:format_exception(2, Class, Reason, StackTrace)]),
[]
end
end, Rows),
diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl
index a02e9178a..c123f6383 100644
--- a/src/gen_iq_handler.erl
+++ b/src/gen_iq_handler.erl
@@ -37,7 +37,7 @@
-include("logger.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("translate.hrl").
--include("ejabberd_stacktrace.hrl").
+
-type component() :: ejabberd_sm | ejabberd_local.
@@ -111,14 +111,14 @@ process_iq(_Host, Module, Function, IQ) ->
ejabberd_router:route(ResIQ);
ignore ->
ok
- catch ?EX_RULE(Class, Reason, St) ->
- StackTrace = ?EX_STACK(St),
- ?ERROR_MSG("Failed to process iq:~n~ts~n** ~ts",
- [xmpp:pp(IQ),
- misc:format_exception(2, Class, Reason, StackTrace)]),
- Txt = ?T("Module failed to handle the query"),
- Err = xmpp:err_internal_server_error(Txt, IQ#iq.lang),
- ejabberd_router:route_error(IQ, Err)
+ catch
+ Class:Reason:StackTrace ->
+ ?ERROR_MSG("Failed to process iq:~n~ts~n** ~ts",
+ [xmpp:pp(IQ),
+ misc:format_exception(2, Class, Reason, StackTrace)]),
+ Txt = ?T("Module failed to handle the query"),
+ Err = xmpp:err_internal_server_error(Txt, IQ#iq.lang),
+ ejabberd_router:route_error(IQ, Err)
end.
-spec process_iq(module(), atom(), iq()) -> ignore | iq().
diff --git a/src/gen_mod.erl b/src/gen_mod.erl
index dc3ba3c56..667ff5055 100644
--- a/src/gen_mod.erl
+++ b/src/gen_mod.erl
@@ -44,7 +44,7 @@
-include("logger.hrl").
-include_lib("stdlib/include/ms_transform.hrl").
--include("ejabberd_stacktrace.hrl").
+
-include("ejabberd_commands.hrl").
-record(ejabberd_module,
@@ -187,16 +187,20 @@ start_module(Host, Module, Opts, Order) ->
ets:delete(ejabberd_modules, {Module, Host}),
erlang:error({bad_return, Module, Err})
end
- catch ?EX_RULE(Class, Reason, Stack) ->
- StackTrace = ?EX_STACK(Stack),
- ets:delete(ejabberd_modules, {Module, Host}),
- ErrorText = format_module_error(
- Module, start, 2,
- Opts, Class, Reason,
- StackTrace),
- ?CRITICAL_MSG(ErrorText, []),
- maybe_halt_ejabberd(),
- erlang:raise(Class, Reason, StackTrace)
+ catch
+ Class:Reason:StackTrace ->
+ ets:delete(ejabberd_modules, {Module, Host}),
+ ErrorText = format_module_error(
+ Module,
+ start,
+ 2,
+ Opts,
+ Class,
+ Reason,
+ StackTrace),
+ ?CRITICAL_MSG(ErrorText, []),
+ maybe_halt_ejabberd(),
+ erlang:raise(Class, Reason, StackTrace)
end.
-spec reload_modules(binary()) -> ok.
@@ -246,14 +250,18 @@ reload_module(Host, Module, NewOpts, OldOpts, Order) ->
{ok, Pid} when is_pid(Pid) -> {ok, Pid};
Err -> erlang:error({bad_return, Module, Err})
end
- catch ?EX_RULE(Class, Reason, Stack) ->
- StackTrace = ?EX_STACK(Stack),
- ErrorText = format_module_error(
- Module, reload, 3,
- NewOpts, Class, Reason,
- StackTrace),
+ catch
+ Class:Reason:StackTrace ->
+ ErrorText = format_module_error(
+ Module,
+ reload,
+ 3,
+ NewOpts,
+ Class,
+ Reason,
+ StackTrace),
?CRITICAL_MSG(ErrorText, []),
- erlang:raise(Class, Reason, StackTrace)
+ erlang:raise(Class, Reason, StackTrace)
end;
false ->
?WARNING_MSG("Module ~ts doesn't support reloading "
@@ -346,14 +354,15 @@ prep_stop_module_keep_config(Host, Module) ->
try Module:prep_stop(Host) of
_ ->
ok
- catch ?EX_RULE(error, undef, _St) ->
- ok;
- ?EX_RULE(Class, Reason, St) ->
- StackTrace = ?EX_STACK(St),
+ catch
+ error:undef:_St ->
+ ok;
+ Class:Reason:StackTrace ->
?ERROR_MSG("Failed to prepare stop module ~ts at ~ts:~n** ~ts",
- [Module, Host,
+ [Module,
+ Host,
misc:format_exception(2, Class, Reason, StackTrace)]),
- error
+ error
end.
-spec stop_module_keep_config(binary(), atom()) -> error | ok.
@@ -371,12 +380,13 @@ stop_module_keep_config(Host, Module) ->
_ ->
ets:delete(ejabberd_modules, {Module, Host}),
ok
- catch ?EX_RULE(Class, Reason, St) ->
- StackTrace = ?EX_STACK(St),
+ catch
+ Class:Reason:StackTrace ->
?ERROR_MSG("Failed to stop module ~ts at ~ts:~n** ~ts",
- [Module, Host,
+ [Module,
+ Host,
misc:format_exception(2, Class, Reason, StackTrace)]),
- error
+ error
end.
-spec add_registrations(binary(), module(), [registration()]) -> ok.
diff --git a/src/mod_block_strangers.erl b/src/mod_block_strangers.erl
index c0a85faf1..fd4e9974d 100644
--- a/src/mod_block_strangers.erl
+++ b/src/mod_block_strangers.erl
@@ -281,9 +281,9 @@ mod_doc() ->
#{value => ?T("AccessName"),
desc =>
?T("The option is supposed to be used when 'allow_local_users' "
- "and 'allow_transports' are not enough. It's an ACL where "
- "'deny' means the message will be rejected (or a CAPTCHA "
- "would be generated for a presence, if configured), and "
+ "and 'allow_transports' are not enough. It's an Access Rule where "
+ "'deny' means the stanza will be rejected; there's an exception "
+ "if option 'captcha' is configured. And "
"'allow' means the sender is whitelisted and the stanza "
"will pass through. The default value is 'none', which "
"means nothing is whitelisted.")}},
@@ -314,8 +314,8 @@ mod_doc() ->
{captcha,
#{value => "true | false",
desc =>
- ?T("Whether to generate CAPTCHA or not in response to "
- "messages from strangers. See also section "
- "_`basic.md#captcha|CAPTCHA`_"
+ ?T("Whether to generate CAPTCHA challenges in response to "
+ "incoming presence subscription requests from strangers. "
+ "See also section _`basic.md#captcha|CAPTCHA`_"
" of the Configuration Guide. "
"The default value is 'false'.")}}]}.
diff --git a/src/mod_http_api.erl b/src/mod_http_api.erl
index 4d7e86777..087be0e72 100644
--- a/src/mod_http_api.erl
+++ b/src/mod_http_api.erl
@@ -36,7 +36,7 @@
-include_lib("xmpp/include/xmpp.hrl").
-include("logger.hrl").
-include("ejabberd_http.hrl").
--include("ejabberd_stacktrace.hrl").
+
-include("translate.hrl").
-define(DEFAULT_API_VERSION, 1000000).
@@ -148,8 +148,7 @@ process([Call | _], #request{method = 'POST', data = Data, ip = IPPort} = Req) -
_:{error,{_,invalid_json}} = Err ->
?DEBUG("Bad Request: ~p", [Err]),
badrequest_response(<<"Invalid JSON input">>);
- ?EX_RULE(_Class, Error, Stack) ->
- StackTrace = ?EX_STACK(Stack),
+ _Class:Error:StackTrace ->
?DEBUG("Bad Request: ~p ~p", [Error, StackTrace]),
badrequest_response()
end;
@@ -166,8 +165,7 @@ process([Call | _], #request{method = 'GET', q = Data, ip = {IP, _}} = Req) ->
%% TODO We need to refactor to remove redundant error return formatting
throw:{error, unknown_command} ->
json_format({404, 44, <<"Command not found.">>});
- ?EX_RULE(_, Error, Stack) ->
- StackTrace = ?EX_STACK(Stack),
+ _:Error:StackTrace ->
?DEBUG("Bad Request: ~p ~p", [Error, StackTrace]),
badrequest_response()
end;
@@ -257,13 +255,15 @@ handle(Call, Auth, Args, Version) when is_atom(Call), is_list(Args) ->
{400, misc:atom_to_binary(Error)};
throw:Msg when is_list(Msg); is_binary(Msg) ->
{400, iolist_to_binary(Msg)};
- ?EX_RULE(Class, Error, Stack) ->
- StackTrace = ?EX_STACK(Stack),
- ?ERROR_MSG("REST API Error: "
- "~ts(~p) -> ~p:~p ~p",
- [Call, hide_sensitive_args(Args),
- Class, Error, StackTrace]),
- {500, <<"internal_error">>}
+ Class:Error:StackTrace ->
+ ?ERROR_MSG("REST API Error: "
+ "~ts(~p) -> ~p:~p ~p",
+ [Call,
+ hide_sensitive_args(Args),
+ Class,
+ Error,
+ StackTrace]),
+ {500, <<"internal_error">>}
end.
handle2(Call, Auth, Args, Version) when is_atom(Call), is_list(Args) ->
diff --git a/src/mod_mix.erl b/src/mod_mix.erl
index ced8ada75..25216b6fc 100644
--- a/src/mod_mix.erl
+++ b/src/mod_mix.erl
@@ -44,7 +44,8 @@
-include_lib("xmpp/include/xmpp.hrl").
-include("logger.hrl").
-include("translate.hrl").
--include("ejabberd_stacktrace.hrl").
+
+
-callback init(binary(), gen_mod:opts()) -> ok | {error, db_failure}.
-callback set_channel(binary(), binary(), binary(),
@@ -319,11 +320,11 @@ handle_cast(Request, State) ->
handle_info({route, Packet}, State) ->
try route(Packet)
- catch ?EX_RULE(Class, Reason, St) ->
- StackTrace = ?EX_STACK(St),
- ?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts",
- [xmpp:pp(Packet),
- misc:format_exception(2, Class, Reason, StackTrace)])
+ catch
+ Class:Reason:StackTrace ->
+ ?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts",
+ [xmpp:pp(Packet),
+ misc:format_exception(2, Class, Reason, StackTrace)])
end,
{noreply, State};
handle_info(Info, State) ->
diff --git a/src/mod_muc.erl b/src/mod_muc.erl
index 0ca31cb80..ffb8c25d7 100644
--- a/src/mod_muc.erl
+++ b/src/mod_muc.erl
@@ -85,7 +85,7 @@
-include("mod_muc.hrl").
-include("mod_muc_room.hrl").
-include("translate.hrl").
--include("ejabberd_stacktrace.hrl").
+
-type state() :: #{hosts := [binary()],
server_host := binary(),
@@ -454,11 +454,11 @@ handle_call({create, Room, Host, From, Nick, Opts}, _From,
-spec handle_cast(term(), state()) -> {noreply, state()}.
handle_cast({route_to_room, Packet}, #{server_host := ServerHost} = State) ->
try route_to_room(Packet, ServerHost)
- catch ?EX_RULE(Class, Reason, St) ->
- StackTrace = ?EX_STACK(St),
+ catch
+ Class:Reason:StackTrace ->
?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts",
- [xmpp:pp(Packet),
- misc:format_exception(2, Class, Reason, StackTrace)])
+ [xmpp:pp(Packet),
+ misc:format_exception(2, Class, Reason, StackTrace)])
end,
{noreply, State};
handle_cast({room_destroyed, {Room, Host}, Pid},
@@ -483,11 +483,11 @@ handle_info({route, Packet}, #{server_host := ServerHost} = State) ->
%% where mod_muc is not loaded. Such configuration
%% is *highly* discouraged
try route(Packet, ServerHost)
- catch ?EX_RULE(Class, Reason, St) ->
- StackTrace = ?EX_STACK(St),
+ catch
+ Class:Reason:StackTrace ->
?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts",
- [xmpp:pp(Packet),
- misc:format_exception(2, Class, Reason, StackTrace)])
+ [xmpp:pp(Packet),
+ misc:format_exception(2, Class, Reason, StackTrace)])
end,
{noreply, State};
handle_info({room_destroyed, {Room, Host}, Pid}, State) ->
diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl
index b4148b33f..c90fde530 100644
--- a/src/mod_muc_room.erl
+++ b/src/mod_muc_room.erl
@@ -74,7 +74,7 @@
-include_lib("xmpp/include/xmpp.hrl").
-include("translate.hrl").
-include("mod_muc_room.hrl").
--include("ejabberd_stacktrace.hrl").
+
-define(MAX_USERS_DEFAULT_LIST,
[5, 10, 20, 30, 50, 100, 200, 500, 1000, 2000, 5000]).
@@ -1027,10 +1027,10 @@ terminate(Reason, _StateName,
ok
end
end
- catch ?EX_RULE(E, R, St) ->
- StackTrace = ?EX_STACK(St),
- ?ERROR_MSG("Got exception on room termination:~n** ~ts",
- [misc:format_exception(2, E, R, StackTrace)])
+ catch
+ E:R:StackTrace ->
+ ?ERROR_MSG("Got exception on room termination:~n** ~ts",
+ [misc:format_exception(2, E, R, StackTrace)])
end.
%%%----------------------------------------------------------------------
@@ -2468,6 +2468,10 @@ check_password(owner, _Affiliation, _Packet, _From,
_StateData) ->
%% Don't check pass if user is owner in MUC service (access_admin option)
true;
+check_password(_ServiceAffiliation, owner, _Packet, _From,
+ _StateData) ->
+ %% Don't check pass if user is owner in this room
+ true;
check_password(_ServiceAffiliation, Affiliation, Packet,
From, StateData) ->
case (StateData#state.config)#config.password_protected
@@ -3266,19 +3270,20 @@ process_item_change(Item, SD, UJID) ->
maybe_send_affiliation(JID, A, SD1),
SD1
end
- catch ?EX_RULE(E, R, St) ->
- StackTrace = ?EX_STACK(St),
- FromSuffix = case UJID of
- #jid{} ->
- JidString = jid:encode(UJID),
- <<" from ", JidString/binary>>;
- undefined ->
- <<"">>
- end,
- ?ERROR_MSG("Failed to set item ~p~ts:~n** ~ts",
- [Item, FromSuffix,
- misc:format_exception(2, E, R, StackTrace)]),
- {error, xmpp:err_internal_server_error()}
+ catch
+ E:R:StackTrace ->
+ FromSuffix = case UJID of
+ #jid{} ->
+ JidString = jid:encode(UJID),
+ <<" from ", JidString/binary>>;
+ undefined ->
+ <<"">>
+ end,
+ ?ERROR_MSG("Failed to set item ~p~ts:~n** ~ts",
+ [Item,
+ FromSuffix,
+ misc:format_exception(2, E, R, StackTrace)]),
+ {error, xmpp:err_internal_server_error()}
end.
-spec unsubscribe_from_room(jid(), state()) -> ok | error.
diff --git a/src/mod_proxy65_service.erl b/src/mod_proxy65_service.erl
index 692ad146d..2d170ed68 100644
--- a/src/mod_proxy65_service.erl
+++ b/src/mod_proxy65_service.erl
@@ -40,7 +40,7 @@
-include("logger.hrl").
-include_lib("xmpp/include/xmpp.hrl").
-include("translate.hrl").
--include("ejabberd_stacktrace.hrl").
+
-define(PROCNAME, ejabberd_mod_proxy65_service).
@@ -86,8 +86,8 @@ terminate(_Reason, #state{myhosts = MyHosts}) ->
handle_info({route, Packet}, State) ->
try route(Packet)
- catch ?EX_RULE(Class, Reason, St) ->
- StackTrace = ?EX_STACK(St),
+ catch
+ Class:Reason:StackTrace ->
?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts",
[xmpp:pp(Packet),
misc:format_exception(2, Class, Reason, StackTrace)])
diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl
index 06f0af657..bd0aff20f 100644
--- a/src/mod_pubsub.erl
+++ b/src/mod_pubsub.erl
@@ -46,7 +46,7 @@
-include("pubsub.hrl").
-include("mod_roster.hrl").
-include("translate.hrl").
--include("ejabberd_stacktrace.hrl").
+
-include("ejabberd_commands.hrl").
-define(STDTREE, <<"tree">>).
@@ -748,11 +748,11 @@ handle_cast(Msg, State) ->
handle_info({route, Packet}, State) ->
try route(Packet)
- catch ?EX_RULE(Class, Reason, St) ->
- StackTrace = ?EX_STACK(St),
- ?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts",
- [xmpp:pp(Packet),
- misc:format_exception(2, Class, Reason, StackTrace)])
+ catch
+ Class:Reason:StackTrace ->
+ ?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts",
+ [xmpp:pp(Packet),
+ misc:format_exception(2, Class, Reason, StackTrace)])
end,
{noreply, State};
handle_info(Info, State) ->
@@ -3819,9 +3819,9 @@ tree_action(Host, Function, Args) ->
DBType = mod_pubsub_opt:db_type(ServerHost),
Fun = fun () ->
try tree_call(Host, Function, Args)
- catch ?EX_RULE(Class, Reason, St) when DBType == sql ->
- StackTrace = ?EX_STACK(St),
- ejabberd_sql:abort({exception, Class, Reason, StackTrace})
+ catch
+ Class:Reason:StackTrace when DBType == sql ->
+ ejabberd_sql:abort({exception, Class, Reason, StackTrace})
end
end,
Ret = case DBType of
@@ -3919,15 +3919,15 @@ transaction(Host, Fun, Trans) ->
do_transaction(ServerHost, Fun, Trans, DBType) ->
F = fun() ->
try Fun()
- catch ?EX_RULE(Class, Reason, St) when (DBType == mnesia andalso
- Trans == transaction) orelse
- DBType == sql ->
- StackTrace = ?EX_STACK(St),
- Ex = {exception, Class, Reason, StackTrace},
- case DBType of
- mnesia -> mnesia:abort(Ex);
- sql -> ejabberd_sql:abort(Ex)
- end
+ catch
+ Class:Reason:StackTrace when (DBType == mnesia andalso
+ Trans == transaction) orelse
+ DBType == sql ->
+ Ex = {exception, Class, Reason, StackTrace},
+ case DBType of
+ mnesia -> mnesia:abort(Ex);
+ sql -> ejabberd_sql:abort(Ex)
+ end
end
end,
Res = case DBType of
diff --git a/src/mod_roster.erl b/src/mod_roster.erl
index 7765fc255..0f032cb02 100644
--- a/src/mod_roster.erl
+++ b/src/mod_roster.erl
@@ -61,7 +61,7 @@
-include("mod_roster.hrl").
-include("ejabberd_http.hrl").
-include("ejabberd_web_admin.hrl").
--include("ejabberd_stacktrace.hrl").
+
-include("translate.hrl").
-define(ROSTER_CACHE, roster_cache).
diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl
index a225ba23b..740ca41d2 100644
--- a/src/mod_vcard.erl
+++ b/src/mod_vcard.erl
@@ -51,7 +51,7 @@
-include_lib("xmpp/include/xmpp.hrl").
-include("mod_vcard.hrl").
-include("translate.hrl").
--include("ejabberd_stacktrace.hrl").
+
-include("ejabberd_http.hrl").
-include("ejabberd_web_admin.hrl").
@@ -151,11 +151,11 @@ handle_cast(Cast, State) ->
handle_info({route, Packet}, State) ->
try route(Packet)
- catch ?EX_RULE(Class, Reason, St) ->
- StackTrace = ?EX_STACK(St),
- ?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts",
- [xmpp:pp(Packet),
- misc:format_exception(2, Class, Reason, StackTrace)])
+ catch
+ Class:Reason:StackTrace ->
+ ?ERROR_MSG("Failed to route packet:~n~ts~n** ~ts",
+ [xmpp:pp(Packet),
+ misc:format_exception(2, Class, Reason, StackTrace)])
end,
{noreply, State};
handle_info(Info, State) ->
diff --git a/tools/make-binaries b/tools/make-binaries
index 51a348d16..22ad3e98c 100755
--- a/tools/make-binaries
+++ b/tools/make-binaries
@@ -65,13 +65,13 @@ fi
rel_name='ejabberd'
rel_vsn=$(git describe --tags | sed -e 's/-g.*//' -e 's/-/./' | tr -d '[:space:]')
mix_vsn=$(mix_version "$rel_vsn")
-crosstool_vsn='1.27.0'
+crosstool_vsn='1.28.0'
termcap_vsn='1.3.1'
-expat_vsn='2.7.1'
+expat_vsn='2.7.2'
zlib_vsn='1.3.1'
yaml_vsn='0.2.5'
-ssl_vsn='3.5.2'
-otp_vsn='27.3.4.2'
+ssl_vsn='3.5.3'
+otp_vsn='27.3.4.3'
elixir_vsn='1.18.4'
pam_vsn='1.6.1' # Newer Linux-PAM versions use Meson, we don't support that yet.
png_vsn='1.6.45'