Mapping the HTTP library into the Application 1⁄2
Firstly we are going to need to wrap up httplib::failure
into a custom
STL exception type before we can type erase it into an exception_ptr
instance. Please note that this code is 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)));
}
}
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. We do, of
course, 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 purpose of the app::make_httplib_exception()
function.