Add RequestFailedException (#717)

* Add RequestFailedException
This commit is contained in:
Victor Vazquez 2020-10-20 22:22:02 -07:00 committed by GitHub
parent a5de5dbd1b
commit 9d47db1d4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 111 additions and 72 deletions

View File

@ -18,6 +18,14 @@
- Prevent pipeline of length zero to be created.
### New Features
- Add `RequestFailException` deriving from `std::runtime_error`.
### Other changes and Improvements
- Updated `TransportException` and `InvalidHeaderException` to derive from `RequestFailedException`.
## 1.0.0-beta.2 (2020-10-09)
### Breaking Changes

View File

@ -0,0 +1,27 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @file
* @brief Define RequestFailedException. It is used by HTTP exceptions.
*/
#pragma once
#include <stdexcept>
namespace Azure { namespace Core {
/**
* @brief An error while trying to send a request to Azure service.
*
*/
struct RequestFailedException : public std::runtime_error
{
/**
* @brief Construct a new Request Failed Exception object.
*
* @param message The error description.
*/
explicit RequestFailedException(std::string const& message) : std::runtime_error(message) {}
};
}} // namespace Azure::Core

View File

@ -8,6 +8,7 @@
#pragma once
#include "azure/core/exception.hpp"
#include "azure/core/http/body_stream.hpp"
#include "azure/core/internal/contract.hpp"
@ -47,6 +48,43 @@ namespace Azure { namespace Core { namespace Http {
std::string const& headerValue);
} // namespace Details
/********************* Exceptions **********************/
/**
* @brief HTTP transport layer error.
*/
struct TransportException : public Azure::Core::RequestFailedException
{
/**
* @brief An error while sending the HTTP request with the transport adapter.
*
* @remark The transport policy will throw this error whenever the transport adapter fail to
* perform a request.
*
* @param message The error description.
*/
explicit TransportException(std::string const& message)
: Azure::Core::RequestFailedException(message)
{
}
};
/**
* @brief An invalid header key name in @Request or @RawResponse.
*
*/
struct InvalidHeaderException : public Azure::Core::RequestFailedException
{
/**
* @brief An invalid header key name detected in the HTTP request or response.
*
* @param message The error description.
*/
explicit InvalidHeaderException(std::string const& message)
: Azure::Core::RequestFailedException(message)
{
}
};
/**
* @brief HTTP transport implementation used.
*/
@ -437,10 +475,10 @@ namespace Azure { namespace Core { namespace Http {
*/
explicit Request(HttpMethod httpMethod, Url url, bool downloadViaStream)
: Request(
httpMethod,
std::move(url),
NullBodyStream::GetNullBodyStream(),
downloadViaStream)
httpMethod,
std::move(url),
NullBodyStream::GetNullBodyStream(),
downloadViaStream)
{
}
@ -524,35 +562,6 @@ namespace Azure { namespace Core { namespace Http {
void StartTry();
};
/*
* RawResponse exceptions
*/
/**
* @brief Couldn't resolve HTTP host.
*/
struct CouldNotResolveHostException : public std::runtime_error
{
explicit CouldNotResolveHostException(std::string const& msg) : std::runtime_error(msg) {}
};
// Any other exception from transport layer without a specific exception defined above
/**
* @brief HTTP transport layer error.
*/
struct TransportException : public std::runtime_error
{
explicit TransportException(std::string const& msg) : std::runtime_error(msg) {}
};
/**
* @brief An invalid header key name in @Request or @RawResponse
*
*/
struct InvalidHeaderException : public std::runtime_error
{
explicit InvalidHeaderException(std::string const& msg) : std::runtime_error(msg) {}
};
/**
* @brief Raw HTTP response.
*/

View File

@ -176,18 +176,8 @@ std::unique_ptr<RawResponse> CurlTransport::Send(Context const& context, Request
if (performing != CURLE_OK)
{
switch (performing)
{
case CURLE_COULDNT_RESOLVE_HOST:
{
throw CouldNotResolveHostException("Could not resolve host " + request.GetUrl().GetHost());
}
default:
{
throw TransportException(
"Error while sending request. " + std::string(curl_easy_strerror(performing)));
}
}
throw Azure::Core::Http::TransportException(
"Error while sending request. " + std::string(curl_easy_strerror(performing)));
}
LogThis("Request completed. Moving response out of session and session to response.");

View File

@ -150,13 +150,6 @@ std::unique_ptr<RawResponse> Azure::Core::Http::RetryPolicy::Send(
return response;
}
}
catch (CouldNotResolveHostException const&)
{
if (!ShouldRetryOnTransportFailure(m_retryOptions, attempt, retryAfter))
{
throw;
}
}
catch (TransportException const&)
{
if (!ShouldRetryOnTransportFailure(m_retryOptions, attempt, retryAfter))

View File

@ -62,11 +62,7 @@ int main()
doDeleteRequest(context, httpPipeline);
doPatchRequest(context, httpPipeline);
}
catch (Http::CouldNotResolveHostException const& e)
{
cout << e.what() << endl;
}
catch (Http::TransportException const& e)
catch (Azure::Core::RequestFailedException const& e)
{
cout << e.what() << endl;
}

View File

@ -7,9 +7,9 @@
*
*/
#include <azure/core/http/pipeline.hpp>
#include <azure/core/http/curl/curl.hpp>
#include <azure/core/http/http.hpp>
#include <azure/core/http/pipeline.hpp>
#include <array>
#include <iostream>
@ -61,11 +61,7 @@ int main()
doNoPathGetRequest(context, httpPipeline);
doPutRequest(context, httpPipeline);
}
catch (Http::CouldNotResolveHostException const& e)
{
cout << e.what() << endl;
}
catch (Http::TransportException const& e)
catch (Azure::Core::RequestFailedException const& e)
{
cout << e.what() << endl;
}
@ -172,7 +168,7 @@ void printStream(Context const& context, std::unique_ptr<Http::RawResponse> resp
}
cout << static_cast<typename std::underlying_type<Http::HttpStatusCode>::type>(
response->GetStatusCode())
response->GetStatusCode())
<< endl;
cout << response->GetReasonPhrase() << endl;
cout << "headers:" << endl;

View File

@ -480,4 +480,31 @@ namespace Azure { namespace Core { namespace Test {
t1.join();
}
TEST_F(TransportAdapter, requestFailedException)
{
Azure::Core::Http::Url host("http://unresolvedHost.org/get");
auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Get, host);
EXPECT_THROW(pipeline.Send(context, request), Azure::Core::RequestFailedException);
}
TEST_F(TransportAdapter, dynamicCast)
{
Azure::Core::Http::Url host("http://unresolvedHost.org/get");
auto request = Azure::Core::Http::Request(Azure::Core::Http::HttpMethod::Get, host);
// test dynamic cast
try
{
auto result = pipeline.Send(context, request);
}
catch (Azure::Core::RequestFailedException& err)
{
// if ref can't be cast, it throws
EXPECT_NO_THROW(dynamic_cast<Azure::Core::Http::TransportException&>(err));
EXPECT_NO_THROW(dynamic_cast<std::runtime_error&>(err));
EXPECT_THROW(dynamic_cast<std::range_error&>(err), std::bad_cast);
}
}
}}} // namespace Azure::Core::Test

View File

@ -77,14 +77,7 @@ namespace Azure { namespace Storage {
break;
}
}
catch (Azure::Core::Http::CouldNotResolveHostException const&)
{
if (lastAttempt)
{
throw;
}
}
catch (Azure::Core::Http::TransportException const&)
catch (Azure::Core::RequestFailedException const&)
{
if (lastAttempt)
{