BOSS 7.1.0
BESIII Offline Software System
|
The goal of the Error Reporting System is to offer tool to simplify and unify error handling and error reporting in TDAQ applications. This package can be used at different levels. At the lowest level, one can simply use the existing checking macros. A more advanced way of using this package is to define specific Issue subclasses.
Basic ERS functionality can be accessed by using simple macros. Those macros are available simply by including the ers/ers.h header file.
The ERS package offers a set of macros to do basic checking. Those macros generally behave like the standard C assert macros. They have the following features:
ERS_STATIC_ASSERT
) those should be used to verity certain assertions at compile-time. For instance if you code rely on certain data structures having certain memory sizes, this can be checked using static assertions. ERS_PRECONDITION
) those should be used to check condition when entering functions. For instance if you only accept certain values for parameters precondtions should verify that those conditions are resepected. ERS_PRE_CHECK_PTR
) this special type of pre-condition checks that a pointer is valid (not null), you should this macro to check all pointers that a function or method receives as parameters. ERS_CHECK_PTR
) this type of checks is used to verify general pointers internally. ERS_ASSERT
) this macro can be used for checks that do not fit into any other category. N_DEBUG
is defined fprintf
like formatting All macros throw Issues object as exceptions with a severity_t of ers::error
. The main difference between the different macros is that the Issue object they generate in case of violated condition contains different information fields. For instance all precondition macros generate issue that specify that the responsiblity for the Issue lies in the caller, not the callee.
The ERS package offers a set of macros to do logging. Those macros construct an issue and send them to the relevant stream. They all support multiple number of parameters with fprintf
like patterns. For each debug and warning severity_t level there is an associated macro:
The actual behaviour of the macro can be set up either at compile or runtime. Debug macros with levels larger than 0 can be disabled at compile time simply by defining the DEBUG_LEVEL. For instance, if DEBUG_LEVEL is 1, then ERS_DEBUG_2 and ERS_DEBUG_3 are compiled out. At runtime the stream associated with a given severity can be disabled by associated a null stream with the severity. A filtering stream can also be associated with the severity level. The different types of streams supported by the package and the debug and warning macros are presented in the documentation for class ers::StreamFactory
For a discussion about building custom issue, see the documentation for the Issue class. An example custom issue is also given in the example directory.
The ERS system use the abstraction of streams to handle issues. Conceptualy, a stream is simply an object that can the user can use to send (or receive) Issues. There is one stream associated with each severity level, those streams can be set or retrieved using methods of the ers::StreamFactory class.
The ERS system offers some facilities to give out standard compliant exit values for programs. That is, if a program exists because of an ers Issue, it can call the exit_value
method on the issue to possibly get an appropriate exit value (as defined in sysexits.h). A typical main program would look like this:
An precondition is a condition that needs to be respected when entering a function, an assertion is a condition that needs to be respected inside a function. A failed precondition indicates that the problem lies outside of the function, a failed assertion indicates that the problem lies inside the function.
The macro ERS_HERE is used to insert all the context information to a ers issue. When constructing an issue one should always give the macro ERS_HERE as a first parameter.
The registration and factory mechanism as implemented in the ExampleIssue class is needed for some functionality of ERS. If it is not present, the system will work but certain features will be disabled. In particular the absence of factory method means that ERS cannot dynamically build instance with the precise C++ type. For instance if you instanciate an CustomIssue that does not declare a factory method, if you serialise this issue to a file and then deserialise it, it will not have the type CustomIssue, but instead will have the type DefaultIssue. The same happens if an Issue is caused by another issue, the cause issue is cloned into the second issue, so if there is no factory method, the clone issue will have the generic type.