summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon MacMullen <simon@rabbitmq.com>2015-02-26 14:54:58 +0000
committerSimon MacMullen <simon@rabbitmq.com>2015-02-26 14:54:58 +0000
commitdb0aaf821c7f41810bd7f2a452205548633355b4 (patch)
tree201effa65b02da24f2a57197323c43d0b42c2d9d
parentcfc289b72cfc2619b4694fe13fa100c64d328018 (diff)
downloadrabbitmq-server-git-db0aaf821c7f41810bd7f2a452205548633355b4.tar.gz
Detangle boot error handling, step 2
We used to have a weird situation where an error inside a boot step would cause us to go through error logging twice. The exception would get caught in run_step/3, then go through boot_error() etc, and basic_boot_error/3 would exit again, leading to more stuff being logged as an application start failure. So to fix that, let's exit with a special atom which prevents further logging. Also rename functions to be a bit more meaningful.
-rw-r--r--src/rabbit.erl40
1 files changed, 24 insertions, 16 deletions
diff --git a/src/rabbit.erl b/src/rabbit.erl
index 7e35224669..de91f8a39d 100644
--- a/src/rabbit.erl
+++ b/src/rabbit.erl
@@ -334,7 +334,11 @@ start_it(StartFun) ->
false -> StartFun()
end
catch
- throw:{could_not_start, _App, _Reason}=Err ->
+ throw:{could_not_start, rabbit,
+ boot_failure_already_logged} ->
+ throw(boot_failure_already_logged),
+ ok;
+ throw:{could_not_start, _App, _Reason} = Err ->
boot_error(Err, wrapper, not_available);
_:Reason ->
boot_error(Reason, wrapper, erlang:get_stacktrace())
@@ -387,7 +391,7 @@ stop_apps(Apps) ->
ok.
handle_app_error(Term) ->
- fun(App, {bad_return, {_MFA, {'EXIT', {ExitReason, _}}}}) ->
+ fun(App, {bad_return, {_MFA, {'EXIT', ExitReason}}}) ->
throw({Term, App, ExitReason});
(App, Reason) ->
throw({Term, App, Reason})
@@ -593,7 +597,7 @@ sort_boot_steps(UnsortedSteps) ->
-spec(boot_error/3 :: (term(), atom(), not_available | [tuple()])
-> no_return()).
-endif.
-boot_error(Term={error, {timeout_waiting_for_tables, _}}, _Step, _Stacktrace) ->
+boot_error({error, {timeout_waiting_for_tables, _}}, _Step, _Stacktrace) ->
AllNodes = rabbit_mnesia:cluster_nodes(all),
{Err, Nodes} =
case AllNodes -- [node()] of
@@ -604,30 +608,34 @@ boot_error(Term={error, {timeout_waiting_for_tables, _}}, _Step, _Stacktrace) ->
"Timeout contacting cluster nodes: ~p.~n", [Ns]),
Ns}
end,
- basic_boot_error(Term,
- Err ++ rabbit_nodes:diagnostics(Nodes) ++ "~n~n", []);
+ log_boot_error_and_exit(
+ Err ++ rabbit_nodes:diagnostics(Nodes) ++ "~n~n", []);
boot_error(Reason, Step, Stacktrace) ->
- Fmt = "Boot step:~n ~p~n~n"
+ Fmt0 = case Step of
+ wrapper -> "";
+ _ -> rabbit_misc:format("Boot step:~n ~p~n~n", [Step])
+ end,
+ Fmt = Fmt0 ++
"Error description:~n ~p~n~n"
"Log files (may contain more information):~n ~s~n ~s~n~n",
- Args = [Step, Reason, log_location(kernel), log_location(sasl)],
- boot_error(Reason, Fmt, Args, Stacktrace).
+ Args = [Reason, log_location(kernel), log_location(sasl)],
+ boot_error1(Fmt, Args, Stacktrace).
-ifdef(use_specs).
--spec(boot_error/4 :: (term(), string(), [any()], not_available | [tuple()])
+-spec(boot_error1/3 :: (string(), [any()], not_available | [tuple()])
-> no_return()).
-endif.
-boot_error(Reason, Fmt, Args, not_available) ->
- basic_boot_error(Reason, Fmt, Args);
-boot_error(Reason, Fmt, Args, Stacktrace) ->
- basic_boot_error(Reason, Fmt ++ "Stack trace:~n ~p~n~n",
- Args ++ [Stacktrace]).
+boot_error1(Fmt, Args, not_available) ->
+ log_boot_error_and_exit(Fmt, Args);
+boot_error1(Fmt, Args, Stacktrace) ->
+ log_boot_error_and_exit(Fmt ++ "Stack trace:~n ~p~n~n",
+ Args ++ [Stacktrace]).
-basic_boot_error(Reason, Format, Args) ->
+log_boot_error_and_exit(Format, Args) ->
io:format("~n~nBOOT FAILED~n===========~n~n" ++ Format, Args),
rabbit_log:info(Format, Args),
timer:sleep(1000),
- exit({?MODULE, failure_during_boot, Reason}).
+ exit(boot_failure_already_logged).
%%---------------------------------------------------------------------------
%% boot step functions