NetServices: Add custom error message to BNetworkRequestError

Change-Id: I03970762531a689e25cd78a1091aecf755ee87ce
This commit is contained in:
Niels Sascha Reedijk
2022-08-07 08:47:19 +01:00
parent 6d1bb0e7ad
commit 9cb56a4881
5 changed files with 75 additions and 14 deletions
+28 -2
View File
@@ -212,15 +212,31 @@ namespace Network {
/*!
\fn BNetworkRequestError::BNetworkRequestError(const char *origin, ErrorType type,
status_t errorCode=B_OK)
status_t errorCode, const BString& customMessage = BString())
\brief Create a new network request error.
\param origin A string representing where this error occured. It is advised
to initialize it to \c __PRETTY_FUNCTION__ by default.
\param type The error type that describes what the issue was that prevented the completion of
the request.
\param errorCode Optional underlying system error. See the \ref BNetworkRequestError::ErrorType
\param errorCode The underlying system error. See the \ref BNetworkRequestError::ErrorType
documentation on which error types expect a system error.
\param customMessage Optional custom message describing the reason or cause for the error.
\since Haiku R1
*/
/*!
\fn BNetworkRequestError::BNetworkRequestError(const char *origin, ErrorType type,
const BString& customMessage = BString())
\brief Create a new network request error.
\param origin A string representing where this error occured. It is advised
to initialize it to \c __PRETTY_FUNCTION__ by default.
\param type The error type that describes what the issue was that prevented the completion of
the request.
\param customMessage Optional custom message describing the reason or cause for the error.
\since Haiku R1
*/
@@ -248,6 +264,16 @@ namespace Network {
*/
/*!
\fn const char* BNetworkRequestError::CustomMessage() const noexcept
\brief Get the custom error message.
\return Get the custom error message. This may be an empty string if it was not set.
\since Haiku R1
*/
/*!
\fn BString encode_to_base64(const BString& string)
\brief Utility function that encodes a \a string to base64 and returns the result.
@@ -61,7 +61,9 @@ public:
};
BNetworkRequestError(const char* origin, ErrorType type,
status_t errorCode = B_OK);
status_t errorCode, const BString& customMessage = BString());
BNetworkRequestError(const char* origin, ErrorType type,
const BString& customMessage = BString());
virtual const char* Message() const noexcept override;
virtual BString DebugMessage() const override;
@@ -69,9 +71,12 @@ public:
ErrorType Type() const noexcept;
status_t ErrorCode() const noexcept;
const char* CustomMessage() const noexcept;
private:
ErrorType fErrorType;
status_t fErrorCode = B_OK;
BString fCustomMessage;
};
@@ -204,8 +204,10 @@ HttpBuffer::Data() const noexcept
HttpBuffer&
HttpBuffer::operator<<(const std::string_view& data)
{
if (data.size() > (fBuffer.capacity() - fBuffer.size()))
throw BNetworkRequestError(__PRETTY_FUNCTION__, BNetworkRequestError::ProtocolError);
if (data.size() > (fBuffer.capacity() - fBuffer.size())) {
throw BNetworkRequestError(__PRETTY_FUNCTION__, BNetworkRequestError::ProtocolError,
"No capacity left in buffer to append data.");
}
for (const auto& character: data)
fBuffer.push_back(static_cast<const std::byte>(character));
@@ -954,13 +954,18 @@ BHttpSession::Request::ReceiveResult()
auto locationField = fFields.FindField("Location");
if (locationField == fFields.end()) {
throw BNetworkRequestError(__PRETTY_FUNCTION__,
BNetworkRequestError::ProtocolError);
BNetworkRequestError::ProtocolError,
"Redirect; the Location field must be present and cannot be found");
}
auto locationString = BString((*locationField).Value().data(),
(*locationField).Value().size());
auto redirect = BHttpSession::Redirect{BUrl(fRequest.Url(), locationString), redirectToGet};
if (!redirect.url.IsValid())
throw BNetworkRequestError(__PRETTY_FUNCTION__, BNetworkRequestError::ProtocolError);
auto redirect =
BHttpSession::Redirect{BUrl(fRequest.Url(), locationString), redirectToGet};
if (!redirect.url.IsValid()) {
throw BNetworkRequestError(__PRETTY_FUNCTION__,
BNetworkRequestError::ProtocolError,
"Redirect; invalid URL in the Location field");
}
// Notify of redirect
SendMessage(UrlEvent::HttpRedirect, [&locationString](BMessage& msg) {
@@ -1009,12 +1014,16 @@ BHttpSession::Request::ReceiveResult()
fNoContent = true;
fParser.SetContentLength(bodyBytesTotal);
} catch (const std::logic_error& e) {
throw BNetworkRequestError(__PRETTY_FUNCTION__, BNetworkRequestError::ProtocolError);
throw BNetworkRequestError(__PRETTY_FUNCTION__,
BNetworkRequestError::ProtocolError,
"Cannot parse Content-Length field value (logic_error)");
}
}
if (bodyBytesTotal == std::nullopt)
throw BNetworkRequestError(__PRETTY_FUNCTION__, BNetworkRequestError::ProtocolError);
if (bodyBytesTotal == std::nullopt) {
throw BNetworkRequestError(__PRETTY_FUNCTION__,
BNetworkRequestError::ProtocolError, "Expected Content-Length field");
}
}
// Move headers to the result and inform listener
@@ -98,8 +98,17 @@ BInvalidUrl::Url() const
// #pragma mark -- BNetworkRequestError
BNetworkRequestError::BNetworkRequestError(const char* origin, ErrorType type, status_t errorCode)
: BError(origin), fErrorType(type), fErrorCode(errorCode)
BNetworkRequestError::BNetworkRequestError(const char* origin, ErrorType type, status_t errorCode,
const BString& customMessage)
: BError(origin), fErrorType(type), fErrorCode(errorCode), fCustomMessage(customMessage)
{
}
BNetworkRequestError::BNetworkRequestError(const char* origin, ErrorType type,
const BString& customMessage)
: BError(origin), fErrorType(type), fCustomMessage(customMessage)
{
}
@@ -134,6 +143,9 @@ BNetworkRequestError::DebugMessage() const
debugMessage << "\n\tUnderlying System Error: " << fErrorCode << " ("
<< strerror(fErrorCode) << ")";
}
if (fCustomMessage.Length() > 0) {
debugMessage << "\n\tAdditional Info: " << fCustomMessage;
}
return debugMessage;
}
@@ -152,6 +164,13 @@ BNetworkRequestError::ErrorCode() const noexcept
}
const char*
BNetworkRequestError::CustomMessage() const noexcept
{
return fCustomMessage.String();
}
// #pragma mark -- Public functions