Mapping the HTTP library into the Application <sup>1</sup>⁄<sub>2</sub> - Boost.Outcome documentation

# Mapping the HTTP library into the Application `1/2`

Firstly, remember that we are the application writer who has the problem of integrating three third party libraries into our application’s Outcome-based failure handling mechanism. We cannot modify those third party library sources; we must be non-intrusive.

We start by dealing with the HTTP library. We will integrate this into our application by wrapping up `httplib::failure` into a custom STL exception type. We then type erase it into an `exception_ptr` instance. Please note that this code is exclusively defined in the `app` namespace:

    namespace app
    {
      // Specialise an exception type for httplib errors
      struct httplib_error : std::runtime_error
      {
        // passthrough
        using std::runtime_error::runtime_error;
        httplib_error(httplib::failure _failure, std::string msg)
            : std::runtime_error(std::move(msg))
            , failure(std::move(_failure))
        {
        }

        // the original failure
        httplib::failure failure;
      };

      // Type erase httplib::result<U> into a httplib_error exception ptr
      template <class U>  //
      inline std::exception_ptr make_httplib_exception(const httplib::result<U> &src)
      {
        std::string str("httplib failed with error ");
        switch(src.error().status)
        {
        case httplib::status_code::success:
          str.append("success");
          break;
        case httplib::status_code::bad_request:
          str.append("bad request");
          break;
        case httplib::status_code::access_denied:
          str.append("access denied");
          break;
        case httplib::status_code::logon_failed:
          str.append("logon failed");
          break;
        case httplib::status_code::forbidden:
          str.append("forbidden");
          break;
        case httplib::status_code::not_found:
          str.append("not found");
          break;
        case httplib::status_code::internal_error:
          str.append("internal error");
          break;
        }
        str.append(" [url was ");
        str.append(src.error().url);
        str.append("]");
        return std::make_exception_ptr(httplib_error(src.error(), std::move(str)));
      }
    }  // namespace app

View this code on Github

Most of the complexity in this code fragment is driven by the need to create some sort of descriptive string for `std::runtime_error` so its `.what()` returns a useful summary of the original failure. This is the main purpose of the `app::make_httplib_exception()` function.

(Note that if you have Reflection in your C++ compiler, it may be possible to script the conversion of enum values to string representations)

The only real thing to note about `app::httplib_error` is that it squirrels away the original `httplib::failure` in case that is ever needed.

Last revised: February 11, 2019 at 13:38:04 UTC