* RequestFailedException includes error information * Fixed test collateral * Added changelog entry for new core version; Added tests to verify response message contains all expected fields
This commit is contained in:
parent
8672f985aa
commit
f4e99416c9
@ -3,10 +3,7 @@
|
||||
## 1.5.0-beta.1 (Unreleased)
|
||||
|
||||
### Features Added
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
### Bugs Fixed
|
||||
- When a `RequestFailedException` exception is thrown, the `what()` method now includes information about the HTTP request which failed.
|
||||
|
||||
### Other Changes
|
||||
|
||||
|
||||
@ -22,6 +22,12 @@ namespace Azure { namespace Core {
|
||||
*/
|
||||
class RequestFailedException : public std::runtime_error {
|
||||
public:
|
||||
/**
|
||||
* @brief The entire HTTP raw response.
|
||||
*
|
||||
*/
|
||||
std::unique_ptr<Azure::Core::Http::RawResponse> RawResponse;
|
||||
|
||||
/**
|
||||
* @brief The HTTP response code.
|
||||
*
|
||||
@ -61,12 +67,6 @@ namespace Azure { namespace Core {
|
||||
*/
|
||||
std::string Message;
|
||||
|
||||
/**
|
||||
* @brief The entire HTTP raw response.
|
||||
*
|
||||
*/
|
||||
std::unique_ptr<Azure::Core::Http::RawResponse> RawResponse;
|
||||
|
||||
/**
|
||||
* @brief Constructs a new `%RequestFailedException` with a \p message string.
|
||||
*
|
||||
@ -96,13 +96,14 @@ namespace Azure { namespace Core {
|
||||
* @param other The `%RequestFailedException` to be copied.
|
||||
*/
|
||||
RequestFailedException(const RequestFailedException& other)
|
||||
: std::runtime_error(other.Message), StatusCode(other.StatusCode),
|
||||
ReasonPhrase(other.ReasonPhrase), ClientRequestId(other.ClientRequestId),
|
||||
RequestId(other.RequestId), ErrorCode(other.ErrorCode), Message(other.Message),
|
||||
: std::runtime_error(other.Message),
|
||||
RawResponse(
|
||||
other.RawResponse
|
||||
? std::make_unique<Azure::Core::Http::RawResponse>(*other.RawResponse)
|
||||
: nullptr)
|
||||
: nullptr),
|
||||
StatusCode(other.StatusCode), ReasonPhrase(other.ReasonPhrase),
|
||||
ClientRequestId(other.ClientRequestId), RequestId(other.RequestId),
|
||||
ErrorCode(other.ErrorCode), Message(other.Message)
|
||||
{
|
||||
}
|
||||
|
||||
@ -132,8 +133,14 @@ namespace Azure { namespace Core {
|
||||
~RequestFailedException() = default;
|
||||
|
||||
private:
|
||||
std::string GetRawResponseField(
|
||||
std::unique_ptr<Azure::Core::Http::RawResponse>& rawResponse,
|
||||
static std::string GetRawResponseField(
|
||||
std::unique_ptr<Azure::Core::Http::RawResponse> const& rawResponse,
|
||||
std::string fieldName);
|
||||
|
||||
/**
|
||||
* @brief Returns a descriptive string for this RawResponse.
|
||||
*/
|
||||
static std::string GetRawResponseErrorMessage(
|
||||
std::unique_ptr<Azure::Core::Http::RawResponse> const& rawResponse);
|
||||
};
|
||||
}} // namespace Azure::Core
|
||||
|
||||
@ -21,25 +21,38 @@ namespace Azure { namespace Core {
|
||||
|
||||
RequestFailedException::RequestFailedException(
|
||||
std::unique_ptr<Azure::Core::Http::RawResponse>& rawResponse)
|
||||
: RequestFailedException("Received an HTTP unsuccessful status code.")
|
||||
: std::runtime_error(GetRawResponseErrorMessage(rawResponse)),
|
||||
RawResponse(std::move(rawResponse)),
|
||||
// These are guaranteed to always be present in the rawResponse.
|
||||
StatusCode(RawResponse->GetStatusCode()), ReasonPhrase(RawResponse->GetReasonPhrase()),
|
||||
// The response body may or may not have these fields
|
||||
ErrorCode(GetRawResponseField(RawResponse, "code")),
|
||||
Message(GetRawResponseField(RawResponse, "message"))
|
||||
{
|
||||
const auto& headers = rawResponse->GetHeaders();
|
||||
|
||||
// These are guaranteed to always be present in the rawResponse.
|
||||
StatusCode = rawResponse->GetStatusCode();
|
||||
ReasonPhrase = rawResponse->GetReasonPhrase();
|
||||
RawResponse = std::move(rawResponse);
|
||||
|
||||
// The response body may or may not have these fields
|
||||
ErrorCode = GetRawResponseField(RawResponse, "code");
|
||||
Message = GetRawResponseField(RawResponse, "message");
|
||||
|
||||
const auto& headers = RawResponse->GetHeaders();
|
||||
ClientRequestId = HttpShared::GetHeaderOrEmptyString(headers, HttpShared::MsClientRequestId);
|
||||
RequestId = HttpShared::GetHeaderOrEmptyString(headers, HttpShared::MsRequestId);
|
||||
}
|
||||
|
||||
std::string RequestFailedException::GetRawResponseErrorMessage(
|
||||
std::unique_ptr<Azure::Core::Http::RawResponse> const& rawResponse)
|
||||
{
|
||||
std::string returnValue("Received an HTTP unsuccessful status code: ");
|
||||
// The status code will always be present in the rawResponse.
|
||||
returnValue += std::to_string(
|
||||
static_cast<typename std::underlying_type<Azure::Core::Http::HttpStatusCode>::type>(
|
||||
rawResponse->GetStatusCode()));
|
||||
|
||||
// If there is a Reason phrase in the rawResponse, add it to the message.
|
||||
if (!rawResponse->GetReasonPhrase().empty())
|
||||
{
|
||||
returnValue += " Reason: " + rawResponse->GetReasonPhrase();
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
std::string RequestFailedException::GetRawResponseField(
|
||||
std::unique_ptr<Azure::Core::Http::RawResponse>& rawResponse,
|
||||
std::unique_ptr<Azure::Core::Http::RawResponse> const& rawResponse,
|
||||
std::string fieldName)
|
||||
{
|
||||
auto& headers = rawResponse->GetHeaders();
|
||||
|
||||
@ -33,7 +33,14 @@ TEST(RequestFailedException, JSONError)
|
||||
EXPECT_EQ(exception.RequestId, "1");
|
||||
EXPECT_EQ(exception.ClientRequestId, "2");
|
||||
EXPECT_EQ(exception.ReasonPhrase, "retry please :");
|
||||
EXPECT_EQ(exception.what(), std::string("Received an HTTP unsuccessful status code."));
|
||||
EXPECT_EQ(std::string(exception.what()).find("Received an HTTP unsuccessful status code"), 0);
|
||||
EXPECT_NE(
|
||||
std::string(exception.what())
|
||||
.find(std::to_string(
|
||||
static_cast<std::underlying_type<Azure::Core::Http::HttpStatusCode>::type>(
|
||||
Azure::Core::Http::HttpStatusCode::ServiceUnavailable))),
|
||||
std::string::npos);
|
||||
EXPECT_NE(std::string(exception.what()).find("retry please :"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST(RequestFailedException, JSONErrorNoError)
|
||||
@ -58,7 +65,14 @@ TEST(RequestFailedException, JSONErrorNoError)
|
||||
EXPECT_EQ(exception.RequestId, "1");
|
||||
EXPECT_EQ(exception.ClientRequestId, "2");
|
||||
EXPECT_EQ(exception.ReasonPhrase, "retry please :");
|
||||
EXPECT_EQ(exception.what(), std::string("Received an HTTP unsuccessful status code."));
|
||||
EXPECT_EQ(std::string(exception.what()).find("Received an HTTP unsuccessful status code"), 0);
|
||||
EXPECT_NE(
|
||||
std::string(exception.what())
|
||||
.find(std::to_string(
|
||||
static_cast<std::underlying_type<Azure::Core::Http::HttpStatusCode>::type>(
|
||||
Azure::Core::Http::HttpStatusCode::ServiceUnavailable))),
|
||||
std::string::npos);
|
||||
EXPECT_NE(std::string(exception.what()).find("retry please :"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST(RequestFailedException, EmptyValues)
|
||||
@ -74,5 +88,11 @@ TEST(RequestFailedException, EmptyValues)
|
||||
EXPECT_EQ(exception.RequestId, std::string());
|
||||
EXPECT_EQ(exception.ClientRequestId, std::string());
|
||||
EXPECT_EQ(exception.ReasonPhrase, std::string());
|
||||
EXPECT_EQ(exception.what(), std::string("Received an HTTP unsuccessful status code."));
|
||||
EXPECT_EQ(std::string(exception.what()).find("Received an HTTP unsuccessful status code"), 0);
|
||||
EXPECT_NE(
|
||||
std::string(exception.what())
|
||||
.find(std::to_string(
|
||||
static_cast<std::underlying_type<Azure::Core::Http::HttpStatusCode>::type>(
|
||||
Azure::Core::Http::HttpStatusCode::None))),
|
||||
std::string::npos);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user