lib/upnp/Error: wrap libupnp errors in std::system_error

This commit is contained in:
Max Kellermann 2022-11-29 00:29:15 +01:00
parent ed08a4bd58
commit 1f33ac3e98
6 changed files with 68 additions and 28 deletions

View File

@ -24,6 +24,7 @@
#endif #endif
#include "lib/upnp/UniqueIxml.hxx" #include "lib/upnp/UniqueIxml.hxx"
#include "lib/upnp/Action.hxx" #include "lib/upnp/Action.hxx"
#include "lib/upnp/Error.hxx"
#include "Directory.hxx" #include "Directory.hxx"
#include "util/NumberParser.hxx" #include "util/NumberParser.hxx"
#include "util/RuntimeError.hxx" #include "util/RuntimeError.hxx"
@ -72,8 +73,7 @@ ContentDirectoryService::readDirSlice(UpnpClient_Handle hdl,
int code = UpnpSendAction(hdl, m_actionURL.c_str(), m_serviceType.c_str(), int code = UpnpSendAction(hdl, m_actionURL.c_str(), m_serviceType.c_str(),
nullptr /*devUDN*/, request, &response); nullptr /*devUDN*/, request, &response);
if (code != UPNP_E_SUCCESS) if (code != UPNP_E_SUCCESS)
throw FormatRuntimeError("UpnpSendAction() failed: %s", throw Upnp::MakeError(code, "UpnpSendAction() failed");
UpnpGetErrorMessage(code));
AtScopeExit(response) { ixmlDocument_free(response); }; AtScopeExit(response) { ixmlDocument_free(response); };
@ -101,8 +101,8 @@ ContentDirectoryService::readDirSlice(UpnpClient_Handle hdl,
int code = UpnpSendAction(hdl, "", m_actionURL, m_serviceType, "Browse", int code = UpnpSendAction(hdl, "", m_actionURL, m_serviceType, "Browse",
actionParams, responseData, &errcode, errdesc); actionParams, responseData, &errcode, errdesc);
if (code != UPNP_E_SUCCESS) if (code != UPNP_E_SUCCESS)
throw FormatRuntimeError("UpnpSendAction() failed: %s", throw Upnp::MakeError(code, "UpnpSendAction() failed");
UpnpGetErrorMessage(code));
const char *p = ""; const char *p = "";
didreadp = 0; didreadp = 0;
for (const auto &entry : responseData) { for (const auto &entry : responseData) {
@ -162,8 +162,7 @@ ContentDirectoryService::search(UpnpClient_Handle hdl,
nullptr /*devUDN*/, nullptr /*devUDN*/,
request.get(), &_response); request.get(), &_response);
if (code != UPNP_E_SUCCESS) if (code != UPNP_E_SUCCESS)
throw FormatRuntimeError("UpnpSendAction() failed: %s", throw Upnp::MakeError(code, "UpnpSendAction() failed");
UpnpGetErrorMessage(code));
UniqueIxmlDocument response(_response); UniqueIxmlDocument response(_response);
@ -196,8 +195,8 @@ ContentDirectoryService::search(UpnpClient_Handle hdl,
int code = UpnpSendAction(hdl, "", m_actionURL, m_serviceType, "Search", int code = UpnpSendAction(hdl, "", m_actionURL, m_serviceType, "Search",
actionParams, responseData, &errcode, errdesc); actionParams, responseData, &errcode, errdesc);
if (code != UPNP_E_SUCCESS) if (code != UPNP_E_SUCCESS)
throw FormatRuntimeError("UpnpSendAction() failed: %s", throw Upnp::MakeError(code, "UpnpSendAction() failed");
UpnpGetErrorMessage(code));
const char *p = ""; const char *p = "";
count = 0; count = 0;
for (const auto &entry : responseData) { for (const auto &entry : responseData) {
@ -238,8 +237,7 @@ ContentDirectoryService::getMetadata(UpnpClient_Handle hdl,
m_serviceType.c_str(), m_serviceType.c_str(),
nullptr /*devUDN*/, request.get(), &_response); nullptr /*devUDN*/, request.get(), &_response);
if (code != UPNP_E_SUCCESS) if (code != UPNP_E_SUCCESS)
throw FormatRuntimeError("UpnpSendAction() failed: %s", throw Upnp::MakeError(code, "UpnpSendAction() failed");
UpnpGetErrorMessage(code));
UniqueIxmlDocument response(_response); UniqueIxmlDocument response(_response);
UPnPDirContent dirbuf; UPnPDirContent dirbuf;
@ -256,8 +254,8 @@ ContentDirectoryService::getMetadata(UpnpClient_Handle hdl,
int code = UpnpSendAction(hdl, "", m_actionURL, m_serviceType, "Browse", int code = UpnpSendAction(hdl, "", m_actionURL, m_serviceType, "Browse",
actionParams, responseData, &errcode, errdesc); actionParams, responseData, &errcode, errdesc);
if (code != UPNP_E_SUCCESS) if (code != UPNP_E_SUCCESS)
throw FormatRuntimeError("UpnpSendAction() failed: %s", throw Upnp::MakeError(code, "UpnpSendAction() failed");
UpnpGetErrorMessage(code));
auto it = std::find_if(responseData.begin(), responseData.end(), [](auto&& entry){ return entry.first == "Result"; }); auto it = std::find_if(responseData.begin(), responseData.end(), [](auto&& entry){ return entry.first == "Result"; });
const char *p = it != responseData.end() ? it->second.c_str() : ""; const char *p = it != responseData.end() ? it->second.c_str() : "";
UPnPDirContent dirbuf; UPnPDirContent dirbuf;

View File

@ -19,9 +19,9 @@
#include "ClientInit.hxx" #include "ClientInit.hxx"
#include "Init.hxx" #include "Init.hxx"
#include "Error.hxx"
#include "Callback.hxx" #include "Callback.hxx"
#include "thread/Mutex.hxx" #include "thread/Mutex.hxx"
#include "util/RuntimeError.hxx"
#include <upnptools.h> #include <upnptools.h>
@ -52,8 +52,7 @@ DoInit()
auto code = UpnpRegisterClient(UpnpClientCallback, nullptr, auto code = UpnpRegisterClient(UpnpClientCallback, nullptr,
&upnp_client_handle); &upnp_client_handle);
if (code != UPNP_E_SUCCESS) if (code != UPNP_E_SUCCESS)
throw FormatRuntimeError("UpnpRegisterClient() failed: %s", throw Upnp::MakeError(code, "UpnpRegisterClient() failed");
UpnpGetErrorMessage(code));
} }
UpnpClient_Handle UpnpClient_Handle

View File

@ -21,13 +21,13 @@
#include "ContentDirectoryService.hxx" #include "ContentDirectoryService.hxx"
#include "Device.hxx" #include "Device.hxx"
#include "Error.hxx"
#include "UniqueIxml.hxx" #include "UniqueIxml.hxx"
#ifdef USING_PUPNP #ifdef USING_PUPNP
# include "ixmlwrap.hxx" # include "ixmlwrap.hxx"
#endif #endif
#include "Action.hxx" #include "Action.hxx"
#include "util/IterableSplitString.hxx" #include "util/IterableSplitString.hxx"
#include "util/RuntimeError.hxx"
#include "util/UriRelative.hxx" #include "util/UriRelative.hxx"
#include "util/UriUtil.hxx" #include "util/UriUtil.hxx"
@ -70,8 +70,7 @@ ContentDirectoryService::getSearchCapabilities(UpnpClient_Handle hdl) const
m_serviceType.c_str(), m_serviceType.c_str(),
nullptr /*devUDN*/, request.get(), &_response); nullptr /*devUDN*/, request.get(), &_response);
if (code != UPNP_E_SUCCESS) if (code != UPNP_E_SUCCESS)
throw FormatRuntimeError("UpnpSendAction() failed: %s", throw Upnp::MakeError(code, "UpnpSendAction() failed");
UpnpGetErrorMessage(code));
UniqueIxmlDocument response(_response); UniqueIxmlDocument response(_response);
@ -85,8 +84,8 @@ ContentDirectoryService::getSearchCapabilities(UpnpClient_Handle hdl) const
"GetSearchCapabilities", {}, responseData, &errcode, "GetSearchCapabilities", {}, responseData, &errcode,
errdesc); errdesc);
if (code != UPNP_E_SUCCESS) if (code != UPNP_E_SUCCESS)
throw FormatRuntimeError("UpnpSendAction() failed: %s", throw Upnp::MakeError(code, "UpnpSendAction() failed");
UpnpGetErrorMessage(code));
const char *s{nullptr}; const char *s{nullptr};
for (auto &entry : responseData) { for (auto &entry : responseData) {
if (entry.first == "SearchCaps") { if (entry.first == "SearchCaps") {

View File

@ -20,12 +20,12 @@
#include "Discovery.hxx" #include "Discovery.hxx"
#include "ContentDirectoryService.hxx" #include "ContentDirectoryService.hxx"
#include "Log.hxx" #include "Log.hxx"
#include "Error.hxx"
#include "lib/curl/Global.hxx" #include "lib/curl/Global.hxx"
#include "event/Call.hxx" #include "event/Call.hxx"
#include "util/DeleteDisposer.hxx" #include "util/DeleteDisposer.hxx"
#include "util/ScopeExit.hxx" #include "util/ScopeExit.hxx"
#include "util/SpanCast.hxx" #include "util/SpanCast.hxx"
#include "util/RuntimeError.hxx"
#include <upnptools.h> #include <upnptools.h>
@ -296,14 +296,12 @@ UPnPDeviceDirectory::Search()
int code = UpnpSearchAsync(handle, search_timeout, int code = UpnpSearchAsync(handle, search_timeout,
ContentDirectorySType, GetUpnpCookie()); ContentDirectorySType, GetUpnpCookie());
if (code != UPNP_E_SUCCESS) if (code != UPNP_E_SUCCESS)
throw FormatRuntimeError("UpnpSearchAsync() failed: %s", throw Upnp::MakeError(code, "UpnpSearchAsync() failed");
UpnpGetErrorMessage(code));
code = UpnpSearchAsync(handle, search_timeout, code = UpnpSearchAsync(handle, search_timeout,
MediaServerDType, GetUpnpCookie()); MediaServerDType, GetUpnpCookie());
if (code != UPNP_E_SUCCESS) if (code != UPNP_E_SUCCESS)
throw FormatRuntimeError("UpnpSearchAsync() failed: %s", throw Upnp::MakeError(code, "UpnpSearchAsync() failed");
UpnpGetErrorMessage(code));
} }
std::vector<ContentDirectoryService> std::vector<ContentDirectoryService>

47
src/lib/upnp/Error.hxx Normal file
View File

@ -0,0 +1,47 @@
/*
* Copyright 2003-2022 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#pragma once
#include <upnptools.h>
#include <system_error>
namespace Upnp {
class ErrorCategory final : public std::error_category {
public:
const char *name() const noexcept override {
return "libupnp";
}
std::string message(int condition) const override {
return UpnpGetErrorMessage(condition);
}
};
inline ErrorCategory error_category;
inline std::system_error
MakeError(int error, const char *msg) noexcept
{
return std::system_error(error, error_category, msg);
}
} // namespace Upnp

View File

@ -19,8 +19,8 @@
#include "Init.hxx" #include "Init.hxx"
#include "Compat.hxx" #include "Compat.hxx"
#include "Error.hxx"
#include "thread/Mutex.hxx" #include "thread/Mutex.hxx"
#include "util/RuntimeError.hxx"
#include <upnptools.h> #include <upnptools.h>
#ifdef USING_PUPNP #ifdef USING_PUPNP
@ -36,8 +36,7 @@ static void
DoInit(const char* iface) DoInit(const char* iface)
{ {
if (auto code = UpnpInit2(iface, 0); code != UPNP_E_SUCCESS) if (auto code = UpnpInit2(iface, 0); code != UPNP_E_SUCCESS)
throw FormatRuntimeError("UpnpInit() failed: %s", throw Upnp::MakeError(code, "UpnpInit() failed");
UpnpGetErrorMessage(code));
UpnpSetMaxContentLength(2000*1024); UpnpSetMaxContentLength(2000*1024);