All implementations of error spaces are derived from this abstract class.
At a conceptual level, an ErrorSpace provides a mechanism for classifying error codes into distinct categories and mapping those errors to human readable strings. It also provides a mechanism for converting error codes from arbitrary error spaces to the Google canonical error space.
At the implementation level, an error space consists of an error code enum and an associated implementation of the abstract ErrorSpace interface. The ErrorSpace interface declares three pure virtual methods. An ErrorSpace interface implementation is bound to the error code enum via a compile-time polymorphic function GetErrorSpace(), which can be used to retrieve a singleton pointer to the error space associated with a particular enum.
Thus, to implement a new error space, the implementer must provide three components:
- An enum type that is not associated with any current ErrorSpace implementation.
- An implementation of the ErrorSpace interface.
- An implementation of an appropriately-typed GetErrorSpace() function.
The error-space library maintains a global map of singletons for all the error-space implementations loaded into the current address space. This map can be queried to retrieve singleton pointers associated with a given name using the ErrorSpace::Find(const string &name) method. To enable seamless bookkeeping of such singletons, the error-space infrastructure defines an intermediate template class called ErrorSpaceImplementationHelper, which is derived from the ErrorSpace abstract class. Any error-space implementation derived from this class is automatically tracked in the error-space singleton global map. The helper class also provides a std::unordered_map-based implementation of the SpaceName() and String() methods, and as a result, error-space implementations derived from this class do not need to provide their own implementation of these methods. It is strongly recommended that all error-space implementations be derived from the ErrorSpaceImplementationHelper. While it is possible to correctly implement an error space without deriving from this class, such an implementation will have to be aware of the error-space infrastructure, and consequently, will be fragile.
Below is an example of implementing a new enum Foo
, and associating it with the ErrorSpace implementation FooErrorSpace
.
First, define the enum type.
Next implement the FooErrorSpace
class by deriving it from ErrorSpaceImplementationHelper<FooErrorSpace>
.
class FooErrorSpace : public ErrorSpaceImplementationHelper<FooErrorSpace> {
public:
using code_type = Foo;
private:
FooErrorSpace() : ErrorSpaceImplementationHelper<FooErrorSpace>{
"FooErrorSpace"} {
AddTranslationMapEntry(...);
...
}
};
Finally, bind the ErrorSpace implementation to the enum by defining appropriate GetErrorSpace() function.
See GoogleErrorSpace for an example implementation.