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
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.