[MOAB-dev] Error handling documentation/examples
Wu, Danqing
wuda at mcs.anl.gov
Mon Feb 8 10:16:53 CST 2016
Paul,
Below is an example on the error handling (for demonstration only, in practice the functions will be MOAB routines):
#include "moab/Core.hpp"
using namespace moab;
// Call hierarchy: A calls B, B calls C, and C calls D
ErrorCode FunctionD()
{
MB_SET_ERR(MB_INDEX_OUT_OF_RANGE, "MB_INDEX_OUT_OF_RANGE occurred");
}
ErrorCode FunctionC()
{
ErrorCode err_code = FunctionD();MB_CHK_ERR(err_code);
return MB_SUCCESS;
}
ErrorCode FunctionB()
{
ErrorCode err_code = FunctionC();MB_CHK_ERR(err_code);
return MB_SUCCESS;
}
ErrorCode FunctionA()
{
ErrorCode err_code = FunctionB();MB_CHK_ERR(err_code);
return MB_SUCCESS;
}
int main()
{
MBErrorHandler_Init();
FunctionA();
MBErrorHandler_Finalize();
return 0;
}
Run result:
MOAB ERROR: --------------------- Error Message ------------------------------------
MOAB ERROR: MB_INDEX_OUT_OF_RANGE occurred!
MOAB ERROR: FunctionD() line 8 in test_error.cpp
MOAB ERROR: FunctionC() line 13 in test_error.cpp
MOAB ERROR: FunctionB() line 20 in test_error.cpp
MOAB ERROR: FunctionA() line 27 in read_error.cpp
[Comments]
1) When an initial error occurs in the call hierarchy, using MB_SET_ERR to call the error handler, which will return an error code and print an error message (the function name and the the line number will also be printed).
2) It is usually necessary to check for return values at each step in the stack using macros like MB_CHK_ERR. This macro will also call the error handler, but unlike MB_SET_ERR, it will only print the function name and the line number (no error message to print)
a) It can return the same error code, exiting the function at an earlier time. Otherwise the function will continue to execute and skip the error.
b) It can provide the information about the function name and the line number. Otherwise the printed out call stack will be incomplete.
3) MB_SET_ERR/MB_CHK_ERR is similar to SETERRQ/CHKERRQ of PETSc.
In practice, functions in the higher level can also issue new error messages, to better interpret the errors from low level calls. For example, MB_INDEX_OUT_OF_RANGE is an low lever error, it is better to also notify user that some kind of operations failed at FunctionB. In this case, we can use MB_CHK_SET_ERR instead of MB_CHK_ERR. I think this feature is originally proposed by Tim and PETSc does not have such a macro.
ErrorCode FunctionB()
{
ErrorCode err_code = FunctionC();MB_CHK_SET_ERR(err_code, "Failed to perform XXXX in FunctionB");
return MB_SUCCESS;
}
The updated output will be
MOAB ERROR: --------------------- Error Message ------------------------------------
MOAB ERROR: MB_INDEX_OUT_OF_RANGE occurred!
MOAB ERROR: FunctionD() line 8 in test_error.cpp
MOAB ERROR: FunctionC() line 13 in read_nc.cpp
MOAB ERROR: --------------------- Error Message ------------------------------------
MOAB ERROR: Failed to perform XXXX in FunctionB!
MOAB ERROR: FunctionB() line 20 in read_nc.cpp
MOAB ERROR: FunctionA() line 27 in read_nc.cpp
In case some functions are not routines that return ErrorCode (no return or return void, return other data types), variaations of the basic error handling macros are also provided in ErrorHandler.hpp
XXX_RET
XXX_RET_VAL
XXX_CONT
Vijay, the behavior is the same as PETSc.
All of the macros will call the error handler function. The error handler function is responsible to print out the stack trace. Information about the function name and line numbers are obtained from the macros and passed to the error handlers for printing.
MB_SET_ERR or SETERRQ is used to set the initial error message. MB_CHK_ERR or CHKERRQ is used to return an error code from the calling function, and provide the line number and function name in the stack trace print out.
Best
Danqing
________________________________________
From: Vijay S. Mahadevan [vijay.m at gmail.com]
Sent: Sunday, February 07, 2016 6:53 PM
To: Paul Wilson; Wu, Danqing
Cc: moab-dev at mcs.anl.gov
Subject: Re: [MOAB-dev] Error handling documentation/examples
Paul, this really depends on whether the error that occurs deep in the
stack is fatal or not. If it is a show stopper, use MB_CHK_SET_ERR,
which will throw an error and produce the call stack. Otherwise,
anywhere up the line, you could handle this through
MB_CHK_ERR_RET/MB_CHK_ERR_CONT and use MB_CHK_ERR when you want to
throw an exception.
> Or once I have checked an
> error at a deeper level, is it less important to call the error macros as I
> return back up the stack?
Every time a non-zero error code is met, the stack is maintained until
a fatal MB_CHK_ERR or variant is called. Once a MB_SUCCESS is
encountered, this stack should be destroyed.
Danqing can you verify if this explanation is correct ? And perhaps an
example/test with both an expected fatal and non-fatal error from down
the stack should help here.
Vijay
On Sat, Feb 6, 2016 at 11:38 AM, Paul Wilson <paul.wilson at wisc.edu> wrote:
> Hi there,
>
> I have found all the error handling macros and mostly understand how they
> all work. What is less clear is the best practice/convention for
> setting/returning errors down a deep call stack. If method A calls method B
> calls method C calls method D, should I necessarily check for return values
> and apply error macros at each step in the stack? Or once I have checked an
> error at a deeper level, is it less important to call the error macros as I
> return back up the stack?
>
> Any examples or guidance are welcome.
>
> Thanks,
> Paul
>
> --
> -- ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ --
> Paul Wilson ~ UW-Madison ~ 608-263-0807 ~ cal: http://go.wisc.edu/pphw-cal
> Professor, Engineering Physics. ~ http://cnerg.engr.wisc.edu
> Faculty Director, Advanced Computing Infrastructure ~ http://aci.wisc.edu
>
More information about the moab-dev
mailing list