You may have noticed that your algorithm functions all return a code
(typically StatusCode
). You may have also noticed that we wrap some
functions inside ANA_CHECK()
inside this tutorial. Both of these
are part of the error handling inside ATLAS code. The short summary
is that if you call a function that returns a status code you should
wrap it inside ANA_CHECK()
and return a status code yourself. The
details follow below.
Within ATLAS there are two status code classes available (StatusCode
and CP::CorrectionCode
) which both work mostly the same. If in doubt
which type of status code to return StatusCode
is typically a safe
choice. Generally status codes have three or four possible values
(though they have may different names):
SUCCESS
: No error occurred. The function did all it promised to do.
FAILURE
: An error occurred. By and large we should not assume we
can continue at this point, and the best strategy is to print an error
message saying what we are doing and return. Generally any function that
returns FAILURE
should also print an error message, even if it is only
reporting that a function it called failed. That way it is a lot easier
for the user to understand at what point the code failed.
RECOVERABLE
: An error occurred but we may be able to proceed (with
caution). This is only supported for StatusCode
, and it indicates
that we ran into some situation that the code couldn’t handle, but we can
still proceed, e.g. we tried to calibrate an object that is in a phase
space region for which there are no calibration constants. If a function
returns RECOVERABLE
it should print out a warning message (even if it
is just reporting that a function it called failed). Whether it is a good
idea to proceed in these situations is rather situation-dependent, but for
analysis it is typically better to fail and abort, then fix the issue and rerun.
OutOfValidity
: This is only supported for CP::CorrectionCode
and
is used by some Combined Performance (CP) tools that are used to provide
calibrations, etc. for physics objects. If the object does not fall within
the validity range of the calibration (such as the pT being too low or eta
being too high), the tool may return this value. If you encounter this, you
need to refer to the CP tool directly to understand what it refers to.
If a function returns a status code you are required to check it. Depending
on the type of status code and the settings for your job, it may simply abort
right then and there, print a warning message at the end of the job (see below),
or do nothing. Since the default thing to do is to print an error message on
failure and return failure, we provided the ANA_CHECK()
macro which does it
for you. In effect if you have a line like
ANA_CHECK (evtStore()->retrieve (eventInfo, "EventInfo"));
that is equivalent to doing something like
if (!evtStore()->retrieve (eventInfo, "EventInfo").isSuccess()) {
ANA_MSG_ERROR (...);
return StatusCode::FAILURE;
}
It is perfectly fine not to use ANA_CHECK()
and just write the
if-statements manually (e.g. to customize the error message), but by
and large the ANA_CHECK macro results in more compact and readable
code.
Sometimes you simply cannot return a status code, e.g. because you are in a constructor which cannot have a return type. For those cases you can do the check via:
ANA_CHECK_THROW (...);
Note that by and large this is strongly discouraged, and status codes should be used wherever possible. It is not that there is anything wrong with exceptions, but simply that using the same mechanism everywhere is a definite plus, particularly when it comes to error handling.
If you look at Athena code you will find that it uses ATH_CHECK()
instead of ANA_CHECK
. There are a couple of differences between the
two:
ANA_CHECK
uses ANA_MSG_*
, while ATH_CHECK
uses ATH_MSG_*
. So
all the comments on the
differences between the two apply to the check macros as well.ANA_CHECK
can handle all kinds of status codes as well as boolean
and pointer types for its argument. ATH_CHECK
can only handle
StatusCode
itself.ANA_CHECK
e.g. to
return an int
. ATH_CHECK
will always return a StatusCode
.This can probably be summarized as saying that if you develop an
Athena component and all you’ll ever see is a StatusCode
then
ATH_CHECK
is probably the better choice, but in all other situations
you should use ANA_CHECK
.
Sometimes your function will return something other than a StatusCode
,
e.g. an int
if you are working inside a main
function. To accommodate
that, you can change the return type for ANA_CHECK
by adding this line
at the beginning of the function:
ANA_CHECK_SET_TYPE (int);
This tells ANA_CHECK()
what type of status code to return. The
default is StatusCode
, so if your function returns anything else you
need to specify it in this way.
Special note: You can use ANA_CHECK()
inside your main()
program
as well if you specify:
int main ()
{
using namespace asg::msgUserCode;
ANA_CHECK_SET_TYPE (int);
...
}
This will then return a non-zero value on error (like main()
should). Be warned that if you leave out ANA_CHECK_SET_TYPE (int);
it will still compile, but return zero on error (which it shouldn’t).
That bug is hard to catch, as it only occurs when another error
occurs.