Return Codes (a.k.a. Status Codes)

Last update: 19 Nov 2024 [History] [Edit]

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.


Converting Failures to Exceptions (optional/advanced)

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.

ANA_CHECK() vs. ATH_CHECK() (optional/advanced)

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.
  • It is possible to adjust the return type of 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.

Changing the Return Type (optional/advanced)

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.