There is a system process with the registered name error_logger
. This process receives all error messages from the Erlang runtime system and error messages sent by the error reporting functions in the module error_logger
.
This section describes the following topics:
Errors are divided into the following three categories:
The system designer has to decide if a process can recover from predicted errors.
The last two categories of errors cause an abnormal termination of the process.
Errors can be reported by propagating an EXIT signal, by producing an error report, or both of these methods. The following table summarizes how the three categories of errors can be reported.
Category | EXIT reason | Error report |
Predicted and recoverable | - | yes |
Predicted and unrecoverable | yes | yes |
Not predicted | yes | - |
Recoverable errors are not reported by EXIT signals because the process does not terminate. Unpredicted errors are only reported by EXIT signals because the program does not take care of these errors.
![]() |
The recovery from predicted errors is interpreted as an internal process error recovery. A process restart, issued by the layer above in the supervision tree, can also be used to recover from errors. |
An unrecoverable, but predicted error can provide meaningful error descriptions, not only in an error report but also through an informative EXIT reason.
It is recommended that the EXIT reason is composed as {Reason,{Mod,Fun,Args}}
where:
Reason
is an informative error descriptor, for example an atom or {atom, Value}
.
{Mod,Fun,Args}
is the Mod
:Fun
(Args
) function where the error is detected.
The error_logger
process receives and handles the following types of errors:
emulator
)
error_logger
module interface functions
error_msg/1
, error_msg/2
, info_msg/1
, info_msg/2
, format/2
, error_report/1
, and info_report/1
.
When the error_logger
process receives an error, it is sent to the the error_logger
on the node which is the group leader process for the process which caused the error.
During system start-up, errors are kept in a buffer and they are also written unformatted to standard out
, because error message handling is determined by the start-up process. The standard error_logger
provides two possibilities:
standard_out
All buffered errors are written again when the intended handler is installed. Initially errors are written in the format {error_logger,Time,Arg1,Arg2}
, where:
Time
is a tuple which contains date and time information
Arg1
and Arg2
are the arguments given to a report function.
When a standard handler is installed, errors are written in the following format:
=ERROR REPORT=== Time ==== Formatted error
Formatted error
error messages, which are reported through the format
or error_msg
functions calls, are produced from Format
and Args
in the same way as in the function io:format/2
. If the error was reported through the supplied error_report(Report)
function, the Report
argument is interpreted and written as follows:
[{Tag,Info}]
, where Tag
and Info
is any term. Each {Tag,Info}
tuple is written on a separate line:
Tag: Info
Other
is written as io_lib:format("~p~n",[Other])
.
It is also possible to use the info_report(Report)
function to format Report
as error_report/1
in the above example, but with the heading:
=INFO REPORT=== Time ====
It is possible to add customized error report handlers to the error_logger
process. This may be desirable in order to satisfy one of the following purposes:
The following two functions are used to add and delete handlers:
add_report_handler
to add a handler
delete_report_handler
to delete a handler.
![]() |
It is strongly recommended that the standard error reporting functions be used. Customized handlers should only be added if they are really needed. |
The error_logger
is implemented with the gen_event
behaviour. This means that an event callback module has to be implemented in order to add an associated error logger handler .
All handlers installed within the error_logger
are notified about errors that are received by the error_logger
. This notification is done by calling handle_event/2
in each callback module.
This means that several actions can be performed when specific events occur. For example, the standard error_logger
behaviour can be accompanied by an SNMP trap which is triggered when a pre-determined level of error messages have been received.
New types of error message can be reported with the error_report/2
and info_report/2
functions. Errors which are reported this way are ignored by the standard error logger handlers and would be lost unless an associated handler has been installed.
The event generated by calling error_logger:error_report(Type, Report)
, and which has to be handled by the added error report handler, is the term:
{error_report, Gleader, {Type, Pid, Report}}
where:
Gleader
is the group leader process of the process which executes the function call.
Type
is a term which identifies the type of the error report.
Pid
is the process identity of the process that issued the error report. The Pid
can be used to determine at which node the report was generated.
Report
is a term which describes the error. This term must be recognized by the customized error report handler.
Substitute info_report
in place of error_report
when calling the error_logger:info_report(Type, Report)
function.
![]() |
No standard error_logger messages are described here. |
The following example illustrates how an error report handler for my_error
type of error messages can be implemented:
-module(my_error_logger_h). -copyright('Copyright (c) 1991-97 Ericsson Telecom AB'). -vsn('$Revision: /main/release/2 $'). -behaviour(gen_event). -export([start/0, stop/0, init/1, handle_event/2, handle_info/2, handle_call/2, terminate/2, report/1]). start() -> error_logger:add_report_handler(my_error_logger_h). stop() -> error_logger:delete_report_handler(my_error_logger_h). report(My_error) -> error_logger:error_report(my_error, My_error). init(_) -> {ok, []}. handle_event({error_report, Gleader, {my_error, Pid, My_error}}, State) -> handle_my_error(Gleader, Pid, My_error), {ok, State}; handle_event(_, State) -> % Ignore all other error messages. {ok, State}. handle_info(_, State) -> {ok, State}. handle_call(_, State) -> {error, bad_query}. terminate(_, _) -> ok. handle_my_error(Gleader, Pid, My_error) when node(Gleader) == node() -> %% do handle the error ok; handle_my_error(_, _, _) -> % Ignore error if Gleader at another node. ok.
The purpose of the error_logger
is to log or write errors. If some other type of event handler is needed it must be implemented as a customized process with another registered name. Refer to the section Events for further information.