![]() |
The TfError system is a developer-level mechanism for use in functions to indicate that a non-fatal error has occurred. The primary use of this facility should be in "cross-interface" code situations. These situations occur when the library being called cannot judge the severity of an error and wishes to record that an error occurred, for the caller to handle if possible. (Errors reported in a thread can only be seen within that thread.)
Note that the use of TfError is not meant to discourage functions from reporting errors by return value or by extra parameter passing. The TfError facility is instead intended as a supplement for code situations in which error return codes or extra parameters are problematic.
A TfError object is posted using the TF_ERROR() macro to indicate an error condition. The function that posts the error is still responsible for maintaining flow of control (that is, returning gracefully to its caller).
Each thread maintains its own separate error list. Calling functions use the TfErrorMark object to detect newly posted errors. Traversal of the list is accomplished via standard iterators.
The following code sample illustrates the use of TfError:
The TF_ERROR macro is always invoked with a diagnostic enum code. See Enum Conventions for an example of registering an enum type and it's values as diagnostic codes. The calling patterns for TF_ERROR() are shown in the following examples:
The argument to the TF_ERROR macro (and the Post() function) can either be a std::string
, or a printf-like formatting string followed by the appropriate arguments. Additionally, an error may have an arbitrary piece of extra data stored with it as follows:
The following patterns show the old (menv2x) way of issuing an error with an error code and an arbitrary piece of extra data (TfDiagnosticInfo). They are still supported only for backwards compatibility. All new code should use the above patterns.
The extra data can be retrieved using GetInfo()
on the diagnostic object:
GetInfo()
will return NULL
if there is no extra data or if it's not holding (exactly) the given type.
The Post() construct always returns an iterator to the just-posted TfError.
Note that the TF_ERROR() macro always causes an immediate printout, even if the error is handled. To suppress the printout, use the macro TF_QUIET_ERROR(), which is otherwise the same as TF_ERROR().
If you have several different error states to distinguish, you should create an enum with multiple values describing the various error states. In a library named Oof, the enum (or enums, should you group error states into different categories) should be declared in a header file named Oof/Error.h.
The enum values should then be registered with the TfEnum registry. This could happen in Oof/Error.cpp.
Also wrap the enum to python in Oof/wrapError.cpp.
The following code allows the enum values to be accessible from python under a scope named Error.
If you would like the enum values to be available directly under the module Oof, then just skip creating the errorTypeScope.
Even if you do not wish to distinguish between error states within a library, the fact that these errors came from the same module of code is in itself useful information. In this case, create an enum with a single value, and pass that value. As a last resort, if you're just too darn lazy to stop and make up an enum with one value, you can just pass in integer zero. Doing this, of course, means that you cannot distinguish this particular error from anyone else who has chosen to do this for their error.