mirror of
https://gitee.com/zyjblog/oatpp.git
synced 2025-01-05 17:42:23 +08:00
Merge pull request #565 from JeremyGuinn/error-handler-enhancements
Add new virtual handleError method to handle the original error
This commit is contained in:
commit
0a3969b157
@ -71,27 +71,34 @@ const auto& OATPP_MACRO_FIRSTARG PARAM_LIST = __request;
|
|||||||
#define OATPP_MACRO_API_CONTROLLER_HEADER_1(TYPE, NAME) \
|
#define OATPP_MACRO_API_CONTROLLER_HEADER_1(TYPE, NAME) \
|
||||||
const auto& __param_str_val_##NAME = __request->getHeader(#NAME); \
|
const auto& __param_str_val_##NAME = __request->getHeader(#NAME); \
|
||||||
if(!__param_str_val_##NAME){ \
|
if(!__param_str_val_##NAME){ \
|
||||||
return ApiController::handleError(Status::CODE_400, "Missing HEADER parameter '" #NAME "'"); \
|
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, "Missing HEADER parameter '" #NAME "'"); \
|
||||||
|
auto eptr = std::make_exception_ptr(httpError); \
|
||||||
|
return ApiController::handleError(eptr); \
|
||||||
} \
|
} \
|
||||||
bool __param_validation_check_##NAME; \
|
bool __param_validation_check_##NAME; \
|
||||||
const auto& NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
const auto& NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
||||||
if(!__param_validation_check_##NAME){ \
|
if(!__param_validation_check_##NAME){ \
|
||||||
return ApiController::handleError(Status::CODE_400, "Invalid HEADER parameter '" #NAME "'. Expected type is '" #TYPE "'"); \
|
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, "Invalid HEADER parameter '" #NAME "'. Expected type is '" #TYPE "'"); \
|
||||||
|
auto eptr = std::make_exception_ptr(httpError); \
|
||||||
|
return ApiController::handleError(eptr); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OATPP_MACRO_API_CONTROLLER_HEADER_2(TYPE, NAME, QUALIFIER) \
|
#define OATPP_MACRO_API_CONTROLLER_HEADER_2(TYPE, NAME, QUALIFIER) \
|
||||||
const auto& __param_str_val_##NAME = __request->getHeader(QUALIFIER); \
|
const auto& __param_str_val_##NAME = __request->getHeader(QUALIFIER); \
|
||||||
if(!__param_str_val_##NAME){ \
|
if(!__param_str_val_##NAME){ \
|
||||||
return ApiController::handleError(Status::CODE_400, \
|
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, oatpp::String("Missing HEADER parameter '") + QUALIFIER + "'"); \
|
||||||
oatpp::String("Missing HEADER parameter '") + QUALIFIER + "'"); \
|
auto eptr = std::make_exception_ptr(httpError); \
|
||||||
|
return ApiController::handleError(eptr); \
|
||||||
} \
|
} \
|
||||||
bool __param_validation_check_##NAME; \
|
bool __param_validation_check_##NAME; \
|
||||||
const auto& NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
const auto& NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
||||||
if(!__param_validation_check_##NAME){ \
|
if(!__param_validation_check_##NAME){ \
|
||||||
return ApiController::handleError(Status::CODE_400, \
|
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, \
|
||||||
oatpp::String("Invalid HEADER parameter '") + \
|
oatpp::String("Invalid HEADER parameter '") + \
|
||||||
QUALIFIER + \
|
QUALIFIER + \
|
||||||
"'. Expected type is '" #TYPE "'"); \
|
"'. Expected type is '" #TYPE "'"); \
|
||||||
|
auto eptr = std::make_exception_ptr(httpError); \
|
||||||
|
return ApiController::handleError(eptr); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OATPP_MACRO_API_CONTROLLER_HEADER(TYPE, PARAM_LIST) \
|
#define OATPP_MACRO_API_CONTROLLER_HEADER(TYPE, PARAM_LIST) \
|
||||||
@ -114,27 +121,35 @@ OATPP_MACRO_API_CONTROLLER_MACRO_SELECTOR(OATPP_MACRO_API_CONTROLLER_HEADER_INFO
|
|||||||
#define OATPP_MACRO_API_CONTROLLER_PATH_1(TYPE, NAME) \
|
#define OATPP_MACRO_API_CONTROLLER_PATH_1(TYPE, NAME) \
|
||||||
const auto& __param_str_val_##NAME = __request->getPathVariable(#NAME); \
|
const auto& __param_str_val_##NAME = __request->getPathVariable(#NAME); \
|
||||||
if(!__param_str_val_##NAME){ \
|
if(!__param_str_val_##NAME){ \
|
||||||
return ApiController::handleError(Status::CODE_400, "Missing PATH parameter '" #NAME "'"); \
|
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, "Missing PATH parameter '" #NAME "'"); \
|
||||||
|
auto eptr = std::make_exception_ptr(httpError); \
|
||||||
|
return ApiController::handleError(eptr); \
|
||||||
} \
|
} \
|
||||||
bool __param_validation_check_##NAME; \
|
bool __param_validation_check_##NAME; \
|
||||||
const auto& NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
const auto& NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
||||||
if(!__param_validation_check_##NAME){ \
|
if(!__param_validation_check_##NAME){ \
|
||||||
return ApiController::handleError(Status::CODE_400, "Invalid PATH parameter '" #NAME "'. Expected type is '" #TYPE "'"); \
|
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, "Invalid PATH parameter '" #NAME "'. Expected type is '" #TYPE "'"); \
|
||||||
|
auto eptr = std::make_exception_ptr(httpError); \
|
||||||
|
return ApiController::handleError(eptr); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OATPP_MACRO_API_CONTROLLER_PATH_2(TYPE, NAME, QUALIFIER) \
|
#define OATPP_MACRO_API_CONTROLLER_PATH_2(TYPE, NAME, QUALIFIER) \
|
||||||
const auto& __param_str_val_##NAME = __request->getPathVariable(QUALIFIER); \
|
const auto& __param_str_val_##NAME = __request->getPathVariable(QUALIFIER); \
|
||||||
if(!__param_str_val_##NAME){ \
|
if(!__param_str_val_##NAME){ \
|
||||||
return ApiController::handleError(Status::CODE_400, \
|
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, \
|
||||||
oatpp::String("Missing PATH parameter '") + QUALIFIER + "'"); \
|
oatpp::String("Missing PATH parameter '") + QUALIFIER + "'"); \
|
||||||
|
auto eptr = std::make_exception_ptr(httpError); \
|
||||||
|
return ApiController::handleError(eptr); \
|
||||||
} \
|
} \
|
||||||
bool __param_validation_check_##NAME; \
|
bool __param_validation_check_##NAME; \
|
||||||
const auto NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
const auto NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
||||||
if(!__param_validation_check_##NAME){ \
|
if(!__param_validation_check_##NAME){ \
|
||||||
return ApiController::handleError(Status::CODE_400, \
|
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, \
|
||||||
oatpp::String("Invalid PATH parameter '") + \
|
oatpp::String("Invalid PATH parameter '") + \
|
||||||
QUALIFIER + \
|
QUALIFIER + \
|
||||||
"'. Expected type is '" #TYPE "'"); \
|
"'. Expected type is '" #TYPE "'"); \
|
||||||
|
auto eptr = std::make_exception_ptr(httpError); \
|
||||||
|
return ApiController::handleError(eptr); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OATPP_MACRO_API_CONTROLLER_PATH(TYPE, PARAM_LIST) \
|
#define OATPP_MACRO_API_CONTROLLER_PATH(TYPE, PARAM_LIST) \
|
||||||
@ -163,27 +178,35 @@ const auto& OATPP_MACRO_FIRSTARG PARAM_LIST = __request->getQueryParameters();
|
|||||||
#define OATPP_MACRO_API_CONTROLLER_QUERY_1(TYPE, NAME) \
|
#define OATPP_MACRO_API_CONTROLLER_QUERY_1(TYPE, NAME) \
|
||||||
const auto& __param_str_val_##NAME = __request->getQueryParameter(#NAME); \
|
const auto& __param_str_val_##NAME = __request->getQueryParameter(#NAME); \
|
||||||
if(!__param_str_val_##NAME){ \
|
if(!__param_str_val_##NAME){ \
|
||||||
return ApiController::handleError(Status::CODE_400, "Missing QUERY parameter '" #NAME "'"); \
|
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, "Missing QUERY parameter '" #NAME "'"); \
|
||||||
|
auto eptr = std::make_exception_ptr(httpError); \
|
||||||
|
return ApiController::handleError(eptr); \
|
||||||
} \
|
} \
|
||||||
bool __param_validation_check_##NAME; \
|
bool __param_validation_check_##NAME; \
|
||||||
const auto& NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
const auto& NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
||||||
if(!__param_validation_check_##NAME){ \
|
if(!__param_validation_check_##NAME){ \
|
||||||
return ApiController::handleError(Status::CODE_400, "Invalid QUERY parameter '" #NAME "'. Expected type is '" #TYPE "'"); \
|
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, "Invalid QUERY parameter '" #NAME "'. Expected type is '" #TYPE "'"); \
|
||||||
|
auto eptr = std::make_exception_ptr(httpError); \
|
||||||
|
return ApiController::handleError(eptr); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OATPP_MACRO_API_CONTROLLER_QUERY_2(TYPE, NAME, QUALIFIER) \
|
#define OATPP_MACRO_API_CONTROLLER_QUERY_2(TYPE, NAME, QUALIFIER) \
|
||||||
const auto& __param_str_val_##NAME = __request->getQueryParameter(QUALIFIER); \
|
const auto& __param_str_val_##NAME = __request->getQueryParameter(QUALIFIER); \
|
||||||
if(!__param_str_val_##NAME){ \
|
if(!__param_str_val_##NAME) \
|
||||||
return ApiController::handleError(Status::CODE_400, \
|
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, \
|
||||||
oatpp::String("Missing QUERY parameter '") + QUALIFIER + "'"); \
|
oatpp::String("Missing QUERY parameter '") + QUALIFIER + "'"); \
|
||||||
|
auto eptr = std::make_exception_ptr(httpError); \
|
||||||
|
return ApiController::handleError(eptr); \
|
||||||
} \
|
} \
|
||||||
bool __param_validation_check_##NAME; \
|
bool __param_validation_check_##NAME; \
|
||||||
const auto& NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
const auto& NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
||||||
if(!__param_validation_check_##NAME){ \
|
if(!__param_validation_check_##NAME){ \
|
||||||
return ApiController::handleError(Status::CODE_400, \
|
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, \
|
||||||
oatpp::String("Invalid QUERY parameter '") + \
|
oatpp::String("Invalid QUERY parameter '") + \
|
||||||
QUALIFIER + \
|
QUALIFIER + \
|
||||||
"'. Expected type is '" #TYPE "'"); \
|
"'. Expected type is '" #TYPE "'"); \
|
||||||
|
auto eptr = std::make_exception_ptr(httpError); \
|
||||||
|
return ApiController::handleError(eptr); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OATPP_MACRO_API_CONTROLLER_QUERY_3(TYPE, NAME, QUALIFIER, DEFAULT) \
|
#define OATPP_MACRO_API_CONTROLLER_QUERY_3(TYPE, NAME, QUALIFIER, DEFAULT) \
|
||||||
@ -193,10 +216,12 @@ if(__param_str_val_##NAME) { \
|
|||||||
bool __param_validation_check_##NAME; \
|
bool __param_validation_check_##NAME; \
|
||||||
NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
|
||||||
if(!__param_validation_check_##NAME){ \
|
if(!__param_validation_check_##NAME){ \
|
||||||
return ApiController::handleError(Status::CODE_400, \
|
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, \
|
||||||
oatpp::String("Invalid QUERY parameter '") + \
|
oatpp::String("Invalid QUERY parameter '") + \
|
||||||
QUALIFIER + \
|
QUALIFIER + \
|
||||||
"'. Expected type is '" #TYPE "'"); \
|
"'. Expected type is '" #TYPE "'"); \
|
||||||
|
auto eptr = std::make_exception_ptr(httpError); \
|
||||||
|
return ApiController::handleError(eptr); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,12 +261,16 @@ if(getDefaultObjectMapper()) { \
|
|||||||
|
|
||||||
#define OATPP_MACRO_API_CONTROLLER_BODY_DTO(TYPE, PARAM_LIST) \
|
#define OATPP_MACRO_API_CONTROLLER_BODY_DTO(TYPE, PARAM_LIST) \
|
||||||
if(!getDefaultObjectMapper()) { \
|
if(!getDefaultObjectMapper()) { \
|
||||||
return ApiController::handleError(Status::CODE_500, "ObjectMapper was NOT set. Can't deserialize the request body."); \
|
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_500, "ObjectMapper was NOT set. Can't deserialize the request body."); \
|
||||||
|
auto eptr = std::make_exception_ptr(httpError); \
|
||||||
|
return ApiController::handleError(eptr); \
|
||||||
} \
|
} \
|
||||||
const auto& OATPP_MACRO_FIRSTARG PARAM_LIST = \
|
const auto& OATPP_MACRO_FIRSTARG PARAM_LIST = \
|
||||||
__request->readBodyToDto<TYPE>(getDefaultObjectMapper().get()); \
|
__request->readBodyToDto<TYPE>(getDefaultObjectMapper().get()); \
|
||||||
if(!OATPP_MACRO_FIRSTARG PARAM_LIST) { \
|
if(!OATPP_MACRO_FIRSTARG PARAM_LIST) { \
|
||||||
return ApiController::handleError(Status::CODE_400, "Missing valid body parameter '" OATPP_MACRO_FIRSTARG_STR PARAM_LIST "'"); \
|
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, "Missing valid body parameter '" OATPP_MACRO_FIRSTARG_STR PARAM_LIST "'"); \
|
||||||
|
auto eptr = std::make_exception_ptr(httpError); \
|
||||||
|
return ApiController::handleError(eptr); \
|
||||||
}
|
}
|
||||||
|
|
||||||
// __INFO
|
// __INFO
|
||||||
|
@ -27,11 +27,7 @@
|
|||||||
namespace oatpp { namespace async {
|
namespace oatpp { namespace async {
|
||||||
|
|
||||||
Error::Error(const std::string& what)
|
Error::Error(const std::string& what)
|
||||||
: m_what(what)
|
: runtime_error(what)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
const char* Error::what() const {
|
|
||||||
return m_what.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
}}
|
@ -33,27 +33,14 @@ namespace oatpp { namespace async {
|
|||||||
/**
|
/**
|
||||||
* Class to hold and communicate errors between Coroutines
|
* Class to hold and communicate errors between Coroutines
|
||||||
*/
|
*/
|
||||||
class Error : public oatpp::base::Countable {
|
class Error : public std::runtime_error, public oatpp::base::Countable {
|
||||||
private:
|
|
||||||
std::string m_what;
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
* @param what - error explanation.
|
* @param what - error explanation.
|
||||||
*/
|
*/
|
||||||
Error(const std::string& what);
|
explicit Error(const std::string& what);
|
||||||
|
|
||||||
/**
|
|
||||||
* Virtual destructor.
|
|
||||||
*/
|
|
||||||
virtual ~Error() = default;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Error explanation.
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
const char* what() const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if error belongs to specified class.
|
* Check if error belongs to specified class.
|
||||||
|
@ -70,6 +70,7 @@ const Status Status::CODE_414(414, "Request-URI Too Large");
|
|||||||
const Status Status::CODE_415(415, "Unsupported Media Type");
|
const Status Status::CODE_415(415, "Unsupported Media Type");
|
||||||
const Status Status::CODE_416(416, "Requested Range Not Satisfiable");
|
const Status Status::CODE_416(416, "Requested Range Not Satisfiable");
|
||||||
const Status Status::CODE_417(417, "Expectation Failed");
|
const Status Status::CODE_417(417, "Expectation Failed");
|
||||||
|
const Status Status::CODE_418(418, "I'm a Teapot");
|
||||||
const Status Status::CODE_422(422, "Unprocessable Entity");
|
const Status Status::CODE_422(422, "Unprocessable Entity");
|
||||||
const Status Status::CODE_423(423, "Locked");
|
const Status Status::CODE_423(423, "Locked");
|
||||||
const Status Status::CODE_424(424, "Failed Dependency");
|
const Status Status::CODE_424(424, "Failed Dependency");
|
||||||
|
@ -246,6 +246,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
static const Status CODE_417;// Expectation Failed
|
static const Status CODE_417;// Expectation Failed
|
||||||
|
|
||||||
|
/**
|
||||||
|
* I'm a Teapot (rfc7168 2.3.3)
|
||||||
|
*/
|
||||||
|
static const Status CODE_418;// I'm a teapot
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unprocessable Entity.
|
* Unprocessable Entity.
|
||||||
*/
|
*/
|
||||||
|
@ -107,21 +107,17 @@ HttpProcessor::processNextRequest(ProcessingResources& resources,
|
|||||||
<< "', URL: '" << request->getStartingLine().path.toString() << "'";
|
<< "', URL: '" << request->getStartingLine().path.toString() << "'";
|
||||||
|
|
||||||
connectionState = ConnectionState::CLOSING;
|
connectionState = ConnectionState::CLOSING;
|
||||||
return resources.components->errorHandler->handleError(protocol::http::Status::CODE_404, ss.toString());
|
oatpp::web::protocol::http::HttpError error(protocol::http::Status::CODE_404, ss.toString());
|
||||||
|
auto ptr = std::make_exception_ptr(error);
|
||||||
|
return resources.components->errorHandler->handleError(ptr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
request->setPathVariables(route.getMatchMap());
|
request->setPathVariables(route.getMatchMap());
|
||||||
return route.getEndpoint()->handle(request);
|
return route.getEndpoint()->handle(request);
|
||||||
|
|
||||||
} catch (oatpp::web::protocol::http::HttpError& error) {
|
|
||||||
response = resources.components->errorHandler->handleError(error.getInfo().status, error.getMessage(), error.getHeaders());
|
|
||||||
connectionState = ConnectionState::CLOSING;
|
|
||||||
} catch (std::exception& error) {
|
|
||||||
response = resources.components->errorHandler->handleError(protocol::http::Status::CODE_500, error.what());
|
|
||||||
connectionState = ConnectionState::CLOSING;
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
response = resources.components->errorHandler->handleError(protocol::http::Status::CODE_500, "Unhandled Error");
|
response = resources.components->errorHandler->handleError(std::current_exception());
|
||||||
connectionState = ConnectionState::CLOSING;
|
connectionState = ConnectionState::CLOSING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,7 +139,9 @@ HttpProcessor::ConnectionState HttpProcessor::processNextRequest(ProcessingResou
|
|||||||
std::shared_ptr<protocol::http::outgoing::Response> response;
|
std::shared_ptr<protocol::http::outgoing::Response> response;
|
||||||
|
|
||||||
if(error.status.code != 0) {
|
if(error.status.code != 0) {
|
||||||
response = resources.components->errorHandler->handleError(error.status, "Invalid Request Headers");
|
oatpp::web::protocol::http::HttpError httpError(error.status, "Invalid Request Headers");
|
||||||
|
auto eptr = std::make_exception_ptr(httpError);
|
||||||
|
response = resources.components->errorHandler->handleError(eptr);
|
||||||
connectionState = ConnectionState::CLOSING;
|
connectionState = ConnectionState::CLOSING;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -160,19 +158,15 @@ HttpProcessor::ConnectionState HttpProcessor::processNextRequest(ProcessingResou
|
|||||||
for (auto& interceptor : resources.components->responseInterceptors) {
|
for (auto& interceptor : resources.components->responseInterceptors) {
|
||||||
response = interceptor->intercept(request, response);
|
response = interceptor->intercept(request, response);
|
||||||
if (!response) {
|
if (!response) {
|
||||||
response = resources.components->errorHandler->handleError(
|
oatpp::web::protocol::http::HttpError httpError(protocol::http::Status::CODE_500, "Response Interceptor returned an Invalid Response - 'null'");
|
||||||
protocol::http::Status::CODE_500,
|
auto eptr = std::make_exception_ptr(httpError);
|
||||||
"Response Interceptor returned an Invalid Response - 'null'"
|
response = resources.components->errorHandler->handleError(eptr);
|
||||||
);
|
|
||||||
connectionState = ConnectionState::CLOSING;
|
connectionState = ConnectionState::CLOSING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
response = resources.components->errorHandler->handleError(
|
response = resources.components->errorHandler->handleError(std::current_exception());
|
||||||
protocol::http::Status::CODE_500,
|
|
||||||
"Unhandled Error in Response Interceptor"
|
|
||||||
);
|
|
||||||
connectionState = ConnectionState::CLOSING;
|
connectionState = ConnectionState::CLOSING;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,7 +321,9 @@ oatpp::async::Action HttpProcessor::Coroutine::onHeadersParsed(const RequestHead
|
|||||||
data::stream::BufferOutputStream ss;
|
data::stream::BufferOutputStream ss;
|
||||||
ss << "No mapping for HTTP-method: '" << headersReadResult.startingLine.method.toString()
|
ss << "No mapping for HTTP-method: '" << headersReadResult.startingLine.method.toString()
|
||||||
<< "', URL: '" << headersReadResult.startingLine.path.toString() << "'";
|
<< "', URL: '" << headersReadResult.startingLine.path.toString() << "'";
|
||||||
m_currentResponse = m_components->errorHandler->handleError(protocol::http::Status::CODE_404, ss.toString());
|
oatpp::web::protocol::http::HttpError error(protocol::http::Status::CODE_404, ss.toString());
|
||||||
|
auto eptr = std::make_exception_ptr(error);
|
||||||
|
m_currentResponse = m_components->errorHandler->handleError(eptr);
|
||||||
m_connectionState = ConnectionState::CLOSING;
|
m_connectionState = ConnectionState::CLOSING;
|
||||||
return yieldTo(&HttpProcessor::Coroutine::onResponseFormed);
|
return yieldTo(&HttpProcessor::Coroutine::onResponseFormed);
|
||||||
}
|
}
|
||||||
@ -352,10 +348,9 @@ HttpProcessor::Coroutine::Action HttpProcessor::Coroutine::onResponseFormed() {
|
|||||||
for(auto& interceptor : m_components->responseInterceptors) {
|
for(auto& interceptor : m_components->responseInterceptors) {
|
||||||
m_currentResponse = interceptor->intercept(m_currentRequest, m_currentResponse);
|
m_currentResponse = interceptor->intercept(m_currentRequest, m_currentResponse);
|
||||||
if(!m_currentResponse) {
|
if(!m_currentResponse) {
|
||||||
m_currentResponse = m_components->errorHandler->handleError(
|
oatpp::web::protocol::http::HttpError error(protocol::http::Status::CODE_500, "Response Interceptor returned an Invalid Response - 'null'");
|
||||||
protocol::http::Status::CODE_500,
|
auto eptr = std::make_exception_ptr(error);
|
||||||
"Response Interceptor returned an Invalid Response - 'null'"
|
m_currentResponse = m_components->errorHandler->handleError(eptr);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -430,7 +425,9 @@ HttpProcessor::Coroutine::Action HttpProcessor::Coroutine::handleError(Error* er
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_currentResponse = m_components->errorHandler->handleError(protocol::http::Status::CODE_500, error->what());
|
oatpp::web::protocol::http::HttpError httpError(protocol::http::Status::CODE_500, error->what());
|
||||||
|
auto eptr = std::make_exception_ptr(httpError);
|
||||||
|
m_currentResponse = m_components->errorHandler->handleError(eptr);
|
||||||
return yieldTo(&HttpProcessor::Coroutine::onResponseFormed);
|
return yieldTo(&HttpProcessor::Coroutine::onResponseFormed);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include "ApiController.hpp"
|
#include "ApiController.hpp"
|
||||||
|
|
||||||
#include "oatpp/web/server/handler/ErrorHandler.hpp"
|
#include "oatpp/web/server/handler/ErrorHandler.hpp"
|
||||||
|
|
||||||
namespace oatpp { namespace web { namespace server { namespace api {
|
namespace oatpp { namespace web { namespace server { namespace api {
|
||||||
@ -49,13 +50,17 @@ std::shared_ptr<ApiController::RequestHandler> ApiController::getEndpointHandler
|
|||||||
|
|
||||||
void ApiController::setErrorHandler(const std::shared_ptr<handler::ErrorHandler>& errorHandler){
|
void ApiController::setErrorHandler(const std::shared_ptr<handler::ErrorHandler>& errorHandler){
|
||||||
m_errorHandler = errorHandler;
|
m_errorHandler = errorHandler;
|
||||||
|
if(!m_errorHandler) {
|
||||||
|
m_errorHandler = handler::DefaultErrorHandler::createShared();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<ApiController::OutgoingResponse> ApiController::handleError(const Status& status, const oatpp::String& message) const {
|
std::shared_ptr<ApiController::OutgoingResponse> ApiController::handleError(const std::exception_ptr& exceptionPtr) const {
|
||||||
if(m_errorHandler) {
|
if(m_errorHandler) {
|
||||||
return m_errorHandler->handleError(status, message);
|
return m_errorHandler->handleError(exceptionPtr);
|
||||||
}
|
}
|
||||||
throw oatpp::web::protocol::http::HttpError(status, message);
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiController::setDefaultAuthorizationHandler(const std::shared_ptr<handler::AuthorizationHandler>& authorizationHandler){
|
void ApiController::setDefaultAuthorizationHandler(const std::shared_ptr<handler::AuthorizationHandler>& authorizationHandler){
|
||||||
|
@ -236,7 +236,8 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
async::Action handleError(async::Error* error) override {
|
async::Action handleError(async::Error* error) override {
|
||||||
auto response = m_handler->m_controller->m_errorHandler->handleError(protocol::http::Status::CODE_500, error->what());
|
auto eptr = std::make_exception_ptr(*error);
|
||||||
|
auto response = m_handler->m_controller->m_errorHandler->handleError(eptr);
|
||||||
return this->_return(response);
|
return this->_return(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,27 +263,22 @@ protected:
|
|||||||
|
|
||||||
if(m_method == nullptr) {
|
if(m_method == nullptr) {
|
||||||
if(m_methodAsync == nullptr) {
|
if(m_methodAsync == nullptr) {
|
||||||
return m_controller->handleError(Status::CODE_500, "[ApiController]: Error. Handler method is nullptr.");
|
throw protocol::http::HttpError(Status::CODE_500, "[ApiController]: Error. Handler method is nullptr.");;
|
||||||
}
|
}
|
||||||
return m_controller->handleError(Status::CODE_500, "[ApiController]: Error. Non-async call to async endpoint.");
|
throw protocol::http::HttpError(Status::CODE_500, "[ApiController]: Error. Non-async call to async endpoint.");;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_controller->m_errorHandler) {
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return (m_controller->*m_method)(request);
|
return (m_controller->*m_method)(request);
|
||||||
} catch (oatpp::web::protocol::http::HttpError& error) {
|
|
||||||
return m_controller->m_errorHandler->handleError(error.getInfo().status, error.getMessage(), error.getHeaders());
|
|
||||||
} catch (std::exception& error) {
|
|
||||||
return m_controller->m_errorHandler->handleError(protocol::http::Status::CODE_500, error.what());
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
return m_controller->m_errorHandler->handleError(protocol::http::Status::CODE_500, "Unknown error");
|
auto response = m_controller->handleError(std::current_exception());
|
||||||
|
if(response != nullptr) {
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (m_controller->*m_method)(request);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
oatpp::async::CoroutineStarterForResult<const std::shared_ptr<OutgoingResponse>&>
|
oatpp::async::CoroutineStarterForResult<const std::shared_ptr<OutgoingResponse>&>
|
||||||
@ -383,18 +379,16 @@ public:
|
|||||||
const Endpoints& getEndpoints();
|
const Endpoints& getEndpoints();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [under discussion]
|
* Set error handler to handle errors that occur during the endpoint's execution
|
||||||
* Set error handler to handle calls to handleError
|
|
||||||
*/
|
*/
|
||||||
void setErrorHandler(const std::shared_ptr<handler::ErrorHandler>& errorHandler);
|
void setErrorHandler(const std::shared_ptr<handler::ErrorHandler>& errorHandler);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [under discussion]
|
* Handle the exception using the registered ErrorHandler or if no handler has been set, uses the DefaultErrorHandler::handleError
|
||||||
* Do not use it directly. This method is under discussion.
|
* @note Does not rethrow an exception anymore, OutgoingResponse has to be returned by the caller!
|
||||||
* Currently returns Response created by registered ErrorHandler or returns Response created by DefaultErrorHandler::handleDefaultError
|
* @note If this handler fails to handle the exception, it will be handled by the connection handlers ErrorHandler.
|
||||||
* Notice: Does not throw the Error anymore, error-response has to be returned by the caller!
|
|
||||||
*/
|
*/
|
||||||
std::shared_ptr<OutgoingResponse> handleError(const Status& status, const oatpp::String& message) const;
|
std::shared_ptr<OutgoingResponse> handleError(const std::exception_ptr& exceptionPtr) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [under discussion]
|
* [under discussion]
|
||||||
|
@ -28,9 +28,36 @@
|
|||||||
|
|
||||||
namespace oatpp { namespace web { namespace server { namespace handler {
|
namespace oatpp { namespace web { namespace server { namespace handler {
|
||||||
|
|
||||||
|
std::shared_ptr<protocol::http::outgoing::Response> ErrorHandler::handleError(const std::exception_ptr& exceptionPtr) {
|
||||||
|
|
||||||
|
std::shared_ptr<protocol::http::outgoing::Response> response;
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
/* Default impl for backwards compatibility until the deprecated methods are removed */
|
||||||
|
try {
|
||||||
|
if(exceptionPtr) {
|
||||||
|
std::rethrow_exception(exceptionPtr);
|
||||||
|
}
|
||||||
|
} catch (protocol::http::HttpError& httpError) {
|
||||||
|
response = handleError(httpError.getInfo().status, httpError.getMessage(), httpError.getHeaders());
|
||||||
|
} catch (std::exception& error) {
|
||||||
|
response = handleError(protocol::http::Status::CODE_500, error.what());
|
||||||
|
} catch (...) {
|
||||||
|
response = handleError(protocol::http::Status::CODE_500, "An unknown error has occurred");
|
||||||
|
}
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
return response;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<protocol::http::outgoing::Response> ErrorHandler::handleError(const protocol::http::Status& status, const oatpp::String& message) {
|
std::shared_ptr<protocol::http::outgoing::Response> ErrorHandler::handleError(const protocol::http::Status& status, const oatpp::String& message) {
|
||||||
Headers headers;
|
Headers headers;
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||||
return handleError(status, message, headers);
|
return handleError(status, message, headers);
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<protocol::http::outgoing::Response>
|
std::shared_ptr<protocol::http::outgoing::Response>
|
||||||
@ -55,4 +82,9 @@ DefaultErrorHandler::handleError(const oatpp::web::protocol::http::Status &statu
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<protocol::http::outgoing::Response>
|
||||||
|
DefaultErrorHandler::handleError(const std::exception_ptr& error) {
|
||||||
|
return ErrorHandler::handleError(error);
|
||||||
|
}
|
||||||
|
|
||||||
}}}}
|
}}}}
|
||||||
|
@ -42,10 +42,17 @@ public:
|
|||||||
typedef web::protocol::http::Headers Headers;
|
typedef web::protocol::http::Headers Headers;
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Virtual destructor since the class is ment to be derived from.
|
* Virtual destructor since the class is meant to be derived from.
|
||||||
* */
|
* */
|
||||||
virtual ~ErrorHandler() = default;
|
virtual ~ErrorHandler() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implement this method!
|
||||||
|
* @param error - &std::exception;.
|
||||||
|
* @return - std::shared_ptr to &id:oatpp::web::protocol::http::outgoing::Response;.
|
||||||
|
*/
|
||||||
|
virtual std::shared_ptr<protocol::http::outgoing::Response> handleError(const std::exception_ptr& exceptionPtr) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implement this method!
|
* Implement this method!
|
||||||
* @param status - &id:oatpp::web::protocol::http::Status;.
|
* @param status - &id:oatpp::web::protocol::http::Status;.
|
||||||
@ -53,6 +60,7 @@ public:
|
|||||||
* @param Headers - &id:oatpp::web::protocol::http::Headers;
|
* @param Headers - &id:oatpp::web::protocol::http::Headers;
|
||||||
* @return - std::shared_ptr to &id:oatpp::web::protocol::http::outgoing::Response;.
|
* @return - std::shared_ptr to &id:oatpp::web::protocol::http::outgoing::Response;.
|
||||||
*/
|
*/
|
||||||
|
[[deprecated]]
|
||||||
virtual
|
virtual
|
||||||
std::shared_ptr<protocol::http::outgoing::Response>
|
std::shared_ptr<protocol::http::outgoing::Response>
|
||||||
handleError(const protocol::http::Status& status, const oatpp::String& message, const Headers& headers) = 0;
|
handleError(const protocol::http::Status& status, const oatpp::String& message, const Headers& headers) = 0;
|
||||||
@ -63,6 +71,7 @@ public:
|
|||||||
* @param message - &id:oatpp::String;.
|
* @param message - &id:oatpp::String;.
|
||||||
* @return - std::shared_ptr to &id:oatpp::web::protocol::http::outgoing::Response;.
|
* @return - std::shared_ptr to &id:oatpp::web::protocol::http::outgoing::Response;.
|
||||||
*/
|
*/
|
||||||
|
[[deprecated]]
|
||||||
std::shared_ptr<protocol::http::outgoing::Response> handleError(const protocol::http::Status& status, const oatpp::String& message);
|
std::shared_ptr<protocol::http::outgoing::Response> handleError(const protocol::http::Status& status, const oatpp::String& message);
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -75,8 +84,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*/
|
*/
|
||||||
DefaultErrorHandler()
|
DefaultErrorHandler() = default;
|
||||||
{}
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -87,6 +95,8 @@ public:
|
|||||||
return std::make_shared<DefaultErrorHandler>();
|
return std::make_shared<DefaultErrorHandler>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<protocol::http::outgoing::Response> handleError(const std::exception_ptr& error) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of &l:ErrorHandler::handleError ();
|
* Implementation of &l:ErrorHandler::handleError ();
|
||||||
* @param status - &id:oatpp::web::protocol::http::Status;.
|
* @param status - &id:oatpp::web::protocol::http::Status;.
|
||||||
|
@ -109,6 +109,7 @@ add_executable(oatppAllTests
|
|||||||
oatpp/web/app/DTOs.hpp
|
oatpp/web/app/DTOs.hpp
|
||||||
oatpp/web/app/ControllerWithInterceptors.hpp
|
oatpp/web/app/ControllerWithInterceptors.hpp
|
||||||
oatpp/web/app/ControllerWithInterceptorsAsync.hpp
|
oatpp/web/app/ControllerWithInterceptorsAsync.hpp
|
||||||
|
oatpp/web/app/ControllerWithErrorHandler.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(oatppAllTests PRIVATE oatpp PRIVATE oatpp-test)
|
target_link_libraries(oatppAllTests PRIVATE oatpp PRIVATE oatpp-test)
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "oatpp/web/app/Client.hpp"
|
#include "oatpp/web/app/Client.hpp"
|
||||||
|
|
||||||
#include "oatpp/web/app/ControllerWithInterceptors.hpp"
|
#include "oatpp/web/app/ControllerWithInterceptors.hpp"
|
||||||
|
#include "oatpp/web/app/ControllerWithErrorHandler.hpp"
|
||||||
#include "oatpp/web/app/Controller.hpp"
|
#include "oatpp/web/app/Controller.hpp"
|
||||||
#include "oatpp/web/app/BasicAuthorizationController.hpp"
|
#include "oatpp/web/app/BasicAuthorizationController.hpp"
|
||||||
#include "oatpp/web/app/BearerAuthorizationController.hpp"
|
#include "oatpp/web/app/BearerAuthorizationController.hpp"
|
||||||
@ -143,6 +144,7 @@ void FullTest::onRun() {
|
|||||||
|
|
||||||
runner.addController(app::Controller::createShared());
|
runner.addController(app::Controller::createShared());
|
||||||
runner.addController(app::ControllerWithInterceptors::createShared());
|
runner.addController(app::ControllerWithInterceptors::createShared());
|
||||||
|
runner.addController(app::ControllerWithErrorHandler::createShared());
|
||||||
runner.addController(app::DefaultBasicAuthorizationController::createShared());
|
runner.addController(app::DefaultBasicAuthorizationController::createShared());
|
||||||
runner.addController(app::BasicAuthorizationController::createShared());
|
runner.addController(app::BasicAuthorizationController::createShared());
|
||||||
runner.addController(app::BearerAuthorizationController::createShared());
|
runner.addController(app::BearerAuthorizationController::createShared());
|
||||||
@ -487,6 +489,13 @@ void FullTest::onRun() {
|
|||||||
OATPP_ASSERT(value == "Hello World!!!");
|
OATPP_ASSERT(value == "Hello World!!!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{ // test controller's error handler catches
|
||||||
|
auto response = client->getCaughtError(connection);
|
||||||
|
OATPP_ASSERT(response->getStatusCode() == 418);
|
||||||
|
auto value = response->readBodyToString();
|
||||||
|
OATPP_ASSERT(value == "Controller With Errors!");
|
||||||
|
}
|
||||||
|
|
||||||
{ // test header replacement
|
{ // test header replacement
|
||||||
auto response = client->getInterceptors(connection);
|
auto response = client->getInterceptors(connection);
|
||||||
OATPP_ASSERT(response->getStatusCode() == 200);
|
OATPP_ASSERT(response->getStatusCode() == 200);
|
||||||
|
@ -76,6 +76,8 @@ public:
|
|||||||
|
|
||||||
API_CALL("GET", "test/interceptors", getInterceptors)
|
API_CALL("GET", "test/interceptors", getInterceptors)
|
||||||
|
|
||||||
|
API_CALL("GET", "test/errorhandling", getCaughtError)
|
||||||
|
|
||||||
API_CALL_HEADERS(getDefaultHeaders1) {
|
API_CALL_HEADERS(getDefaultHeaders1) {
|
||||||
headers.put("X-DEFAULT", "hello_1");
|
headers.put("X-DEFAULT", "hello_1");
|
||||||
}
|
}
|
||||||
|
105
test/oatpp/web/app/ControllerWithErrorHandler.hpp
Normal file
105
test/oatpp/web/app/ControllerWithErrorHandler.hpp
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
*
|
||||||
|
* Project _____ __ ____ _ _
|
||||||
|
* ( _ ) /__\ (_ _)_| |_ _| |_
|
||||||
|
* )(_)( /(__)\ )( (_ _)(_ _)
|
||||||
|
* (_____)(__)(__)(__) |_| |_|
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef oatpp_test_web_app_ControllerWithErrorHandler_hpp
|
||||||
|
#define oatpp_test_web_app_ControllerWithErrorHandler_hpp
|
||||||
|
|
||||||
|
#include "oatpp/web/server/api/ApiController.hpp"
|
||||||
|
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
|
||||||
|
#include "oatpp/core/utils/ConversionUtils.hpp"
|
||||||
|
#include "oatpp/core/macro/codegen.hpp"
|
||||||
|
#include "oatpp/core/macro/component.hpp"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace oatpp { namespace test { namespace web { namespace app {
|
||||||
|
|
||||||
|
namespace http = oatpp::web::protocol::http;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom Error Handler.
|
||||||
|
*/
|
||||||
|
class CustomErrorHandler : public oatpp::base::Countable, public oatpp::web::server::handler::ErrorHandler {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
CustomErrorHandler() = default;
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create shared DefaultErrorHandler.
|
||||||
|
* @return - `std::shared_ptr` to DefaultErrorHandler.
|
||||||
|
*/
|
||||||
|
static std::shared_ptr<CustomErrorHandler> createShared() {
|
||||||
|
return std::make_shared<CustomErrorHandler>();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<http::outgoing::Response> handleError(const std::exception_ptr& error) override {
|
||||||
|
try {
|
||||||
|
std::rethrow_exception(error);
|
||||||
|
} catch(const std::runtime_error& e) {
|
||||||
|
return oatpp::web::protocol::http::outgoing::ResponseFactory::createResponse(http::Status::CODE_418, e.what());
|
||||||
|
} catch(...) {
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response> handleError(const http::Status& status, const oatpp::String& message, const Headers& headers) override {
|
||||||
|
throw std::logic_error("Function not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class ControllerWithErrorHandler : public oatpp::web::server::api::ApiController {
|
||||||
|
private:
|
||||||
|
static constexpr const char* TAG = "test::web::app::ControllerWithErrorHandler";
|
||||||
|
public:
|
||||||
|
explicit ControllerWithErrorHandler(const std::shared_ptr<ObjectMapper>& objectMapper)
|
||||||
|
: oatpp::web::server::api::ApiController(objectMapper)
|
||||||
|
{
|
||||||
|
setErrorHandler(CustomErrorHandler::createShared());
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
|
||||||
|
static std::shared_ptr<ControllerWithErrorHandler> createShared(const std::shared_ptr<ObjectMapper>& objectMapper = OATPP_GET_COMPONENT(std::shared_ptr<ObjectMapper>)){
|
||||||
|
return std::make_shared<ControllerWithErrorHandler>(objectMapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include OATPP_CODEGEN_BEGIN(ApiController)
|
||||||
|
|
||||||
|
ENDPOINT("GET", "test/errorhandling", errorCaught,
|
||||||
|
REQUEST(std::shared_ptr<IncomingRequest>, request))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Controller With Errors!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#include OATPP_CODEGEN_END(ApiController)
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}}}}
|
||||||
|
|
||||||
|
#endif /* oatpp_test_web_app_ControllerWithErrorHandler_hpp */
|
Loading…
Reference in New Issue
Block a user