Chapter 55. Boost.System

    is the most basic class in Boost.System; it represents operating system-specific errors. Because operating systems typically enumerate errors, boost::system::error_code saves an error code in a variable of type int. Example 55.1 illustrates how to use this class.

    Example 55.1. Using boost::system::error_code

    defines the function fail(), which is used to return an error. In order for the caller to detect whether fail() failed, an object of type boost::system::error_code is passed by reference. Many functions that are provided by Boost libraries use boost::system::error_code like this. For example, Boost.Asio provides the function boost::asio::ip::host_name(), to which you can pass an object of type boost::system::error_code.

    Boost.System defines numerous error codes in the namespace boost::system::errc. Example 55.1 assigns the error code boost::system::errc::notsupported to _ec. Because boost::system::errc::not_supported is a number and ec is an object of type boost::system::error_code, the function boost::system::errc::make_error_code() is called. This function creates an object of type boost::system::error_code with the respective error code.

    In main(), value() is called on ec. This member function returns the error code stored in the object.

    By default, 0 means no error. Every other number refers to an error. Error code values are operating system dependent. Refer to the documentation for your operating system for a description of error codes.

    In addition to value(), boost::system::error_code provides the member function category(), which returns an object of type boost::system::error_category.

    Error codes are simply numeric values. While operating system manufacturers such as Microsoft are able to guarantee the uniqueness of system error codes, keeping error codes unique across all existing applications is virtually impossible for application developers. It would require a central database filled with error codes from all software developers around the world to avoid reusing the same codes for different errors. Because this is impractical, error categories exist.

    Example 55.2. Using boost::system::error_category

    As shown in , category() returns an error’s category. This is an object of type boost::system::error_category. There are only a few member functions. For example, name() retrieves the name of the category. Example 55.2 writes generic to standard output.

    You can also use the free-standing function boost::system::generic_category() to access the generic category.

    Boost.System provides a second category. If you call the free-standing function boost::system::system_category(), you get a reference to the system category. If you write the category’s name to standard output, system is displayed.

    Errors are uniquely identified by the error code and the error category. Because error codes are only required to be unique within a category, you should create a new category whenever you want to define error codes specific to your program. This makes it possible to use error codes that do not interfere with error codes from other developers.

    Example 55.3. Creating error categories

    A new error category is defined by creating a class derived from boost::system::error_category. This requires you to define various member functions. At a minimum, the member functions name() and message() must be supplied because they are defined as pure virtual member functions in boost::system::error_category. For additional member functions, the default behavior can be overridden if required.

    While name() returns the name of the error category, message() is used to retrieve the error description for a particular error code. Unlike , the parameter ev is usually evaluated to return a description based on the error code.

    To compile Example 55.3 with Visual C++ 2013, remove the keyword noexcept. This version of the Microsoft compiler doesn’t support noexcept.

    boost::system::error_code provides a member function called default_error_condition(), that returns an object of type boost::system::error_condition. The interface of boost::system::error_condition is almost identical to the interface of boost::system::error_code. The only difference is the member function , which is only provided by boost::system::error_code.

    Example 55.4. Using boost::system::error_condition

    boost::system::error_condition is used just like boost::system::error_code. That’s why it’s possible, as shown in , to call the member functions value() and category() for an object of type boost::system::error_condition.

    While the class boost::system::error_code is used for platform-dependent error codes, boost::system::error_condition is used to access platform-independent error codes. The member function default_error_condition() translates a platform-dependent error code into a platform-independent error code of type boost::system::error_condition.

    You can use boost::system::error_condition to identify errors that are platform independent. Such an error could be, for example, a failed access to a non-existing file. While operating systems may provide different interfaces to access files and may return different error codes, trying to access a non-existing file is an error on all operating systems. The error code returned from operating system specific interfaces is stored in boost::system::error_code. The error code that describes the failed access to a non-existing file is stored in boost::system::error_condition.

    The last class provided by Boost.System is boost::system::system_error, which is derived from std::runtime_error. It can be used to transport an error code of type boost::system::error_code in an exception.

    Example 55.5. Using boost::system::system_error