mirror of
https://github.com/badaix/snapcast.git
synced 2025-04-28 09:47:09 +02:00
Fix RPC error results
This commit is contained in:
parent
9e6009cad0
commit
ea07cb715d
3 changed files with 48 additions and 28 deletions
|
@ -1,6 +1,6 @@
|
|||
/***
|
||||
This file is part of snapcast
|
||||
Copyright (C) 2014-2024 Johannes Pohl
|
||||
Copyright (C) 2014-2025 Johannes Pohl
|
||||
|
||||
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
|
||||
|
@ -34,6 +34,17 @@
|
|||
static constexpr auto LOG_TAG = "ControlRequest";
|
||||
|
||||
|
||||
/// throw InvalidParamsException if one of @p params is missing in @p request
|
||||
static void checkParams(const jsonrpcpp::request_ptr& request, const std::vector<std::string>& params)
|
||||
{
|
||||
for (const auto& param : params)
|
||||
{
|
||||
if (!request->params().has(param))
|
||||
throw jsonrpcpp::InvalidParamsException("Parameter '" + param + "' is missing", request->id());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Request::Request(const Server& server, const std::string& method) : server_(server), method_(method)
|
||||
{
|
||||
}
|
||||
|
@ -120,8 +131,7 @@ ClientRequest::ClientRequest(const Server& server, const std::string& method) :
|
|||
|
||||
ClientInfoPtr ClientRequest::getClient(const jsonrpcpp::request_ptr& request)
|
||||
{
|
||||
if (!request->params().has("id"))
|
||||
throw jsonrpcpp::InvalidParamsException("Parameter 'id' is missing", request->id());
|
||||
checkParams(request, {"id"});
|
||||
|
||||
ClientInfoPtr clientInfo = Config::instance().getClientInfo(request->params().get<std::string>("id"));
|
||||
if (clientInfo == nullptr)
|
||||
|
@ -180,6 +190,8 @@ void ClientSetVolumeRequest::execute(const jsonrpcpp::request_ptr& request, Auth
|
|||
// Notification: {"jsonrpc":"2.0","method":"Client.OnVolumeChanged","params":{"id":"00:21:6a:7d:74:fc","volume":{"muted":false,"percent":74}}}
|
||||
// clang-format on
|
||||
|
||||
checkParams(request, {"volume"});
|
||||
|
||||
std::ignore = authinfo;
|
||||
auto client_info = getClient(request);
|
||||
client_info->config.volume.fromJson(request->params().get("volume"));
|
||||
|
@ -207,6 +219,8 @@ void ClientSetLatencyRequest::execute(const jsonrpcpp::request_ptr& request, Aut
|
|||
// Notification: {"jsonrpc":"2.0","method":"Client.OnLatencyChanged","params":{"id":"00:21:6a:7d:74:fc#2","latency":10}}
|
||||
// clang-format on
|
||||
|
||||
checkParams(request, {"latency"});
|
||||
|
||||
std::ignore = authinfo;
|
||||
int latency = request->params().get("latency");
|
||||
if (latency < -10000)
|
||||
|
@ -239,6 +253,8 @@ void ClientSetNameRequest::execute(const jsonrpcpp::request_ptr& request, AuthIn
|
|||
// Notification: {"jsonrpc":"2.0","method":"Client.OnNameChanged","params":{"id":"00:21:6a:7d:74:fc#2","name":"Laptop"}}
|
||||
// clang-format on
|
||||
|
||||
checkParams(request, {"name"});
|
||||
|
||||
std::ignore = authinfo;
|
||||
auto client_info = getClient(request);
|
||||
client_info->config.name = request->params().get<std::string>("name");
|
||||
|
@ -264,8 +280,7 @@ GroupRequest::GroupRequest(const Server& server, const std::string& method) : Re
|
|||
|
||||
GroupPtr GroupRequest::getGroup(const jsonrpcpp::request_ptr& request)
|
||||
{
|
||||
if (!request->params().has("id"))
|
||||
throw jsonrpcpp::InvalidParamsException("Parameter 'id' is missing", request->id());
|
||||
checkParams(request, {"id"});
|
||||
|
||||
GroupPtr group = Config::instance().getGroup(request->params().get<std::string>("id"));
|
||||
if (group == nullptr)
|
||||
|
@ -306,6 +321,8 @@ void GroupSetNameRequest::execute(const jsonrpcpp::request_ptr& request, AuthInf
|
|||
// Notification: {"jsonrpc":"2.0","method":"Group.OnNameChanged","params":{"id":"4dcc4e3b-c699-a04b-7f0c-8260d23c43e1","MediaPlayer":"Laptop"}}
|
||||
// clang-format on
|
||||
|
||||
checkParams(request, {"name"});
|
||||
|
||||
std::ignore = authinfo;
|
||||
Json result;
|
||||
auto group = getGroup(request);
|
||||
|
@ -330,6 +347,8 @@ void GroupSetMuteRequest::execute(const jsonrpcpp::request_ptr& request, AuthInf
|
|||
// Notification: {"jsonrpc":"2.0","method":"Group.OnMute","params":{"id":"4dcc4e3b-c699-a04b-7f0c-8260d23c43e1","mute":true}}
|
||||
// clang-format on
|
||||
|
||||
checkParams(request, {"mute"});
|
||||
|
||||
std::ignore = authinfo;
|
||||
bool muted = request->params().get<bool>("mute");
|
||||
auto group = getGroup(request);
|
||||
|
@ -372,6 +391,8 @@ void GroupSetStreamRequest::execute(const jsonrpcpp::request_ptr& request, AuthI
|
|||
// Notification: {"jsonrpc":"2.0","method":"Group.OnStreamChanged","params":{"id":"4dcc4e3b-c699-a04b-7f0c-8260d23c43e1","stream_id":"stream 1"}}
|
||||
// clang-format on
|
||||
|
||||
checkParams(request, {"stream_id"});
|
||||
|
||||
std::ignore = authinfo;
|
||||
auto streamId = request->params().get<std::string>("stream_id");
|
||||
PcmStreamPtr stream = getStreamManager().getStream(streamId);
|
||||
|
@ -415,6 +436,8 @@ void GroupSetClientsRequest::execute(const jsonrpcpp::request_ptr& request, Auth
|
|||
// Notification: {"jsonrpc":"2.0","method":"Server.OnUpdate","params":{"server":{"groups":[{"clients":[{"config":{"instance":2,"latency":6,"name":"123 456","volume":{"muted":false,"percent":48}},"connected":true,"host":{"arch":"x86_64","ip":"127.0.0.1","mac":"00:21:6a:7d:74:fc","name":"T400","os":"Linux Mint 17.3 Rosa"},"id":"00:21:6a:7d:74:fc#2","lastSeen":{"sec":1488025901,"usec":864472},"snapclient":{"name":"Snapclient","protocolVersion":2,"version":"0.10.0"}},{"config":{"instance":1,"latency":0,"name":"","volume":{"muted":false,"percent":100}},"connected":true,"host":{"arch":"x86_64","ip":"127.0.0.1","mac":"00:21:6a:7d:74:fc","name":"T400","os":"Linux Mint 17.3 Rosa"},"id":"00:21:6a:7d:74:fc","lastSeen":{"sec":1488025905,"usec":45238},"snapclient":{"name":"Snapclient","protocolVersion":2,"version":"0.10.0"}}],"id":"4dcc4e3b-c699-a04b-7f0c-8260d23c43e1","muted":false,"name":"","stream_id":"stream 2"}],"server":{"host":{"arch":"x86_64","ip":"","mac":"","name":"T400","os":"Linux Mint 17.3 Rosa"},"snapserver":{"controlProtocolVersion":1,"name":"Snapserver","protocolVersion":1,"version":"0.10.0"}},"streams":[{"id":"stream 1","status":"idle","uri":{"fragment":"","host":"","path":"/tmp/snapfifo","query":{"chunk_ms":"20","codec":"flac","name":"stream 1","sampleformat":"48000:16:2"},"raw":"pipe:///tmp/snapfifo?name=stream 1","scheme":"pipe"}},{"id":"stream 2","status":"idle","uri":{"fragment":"","host":"","path":"/tmp/snapfifo","query":{"chunk_ms":"20","codec":"flac","name":"stream 2","sampleformat":"48000:16:2"},"raw":"pipe:///tmp/snapfifo?name=stream 2","scheme":"pipe"}}]}}}
|
||||
// clang-format on
|
||||
|
||||
checkParams(request, {"clients"});
|
||||
|
||||
std::ignore = authinfo;
|
||||
std::vector<std::string> clients = request->params().get("clients");
|
||||
|
||||
|
@ -496,8 +519,7 @@ PcmStreamPtr StreamRequest::getStream(const StreamManager& stream_manager, const
|
|||
|
||||
std::string StreamRequest::getStreamId(const jsonrpcpp::request_ptr& request)
|
||||
{
|
||||
if (!request->params().has("id"))
|
||||
throw jsonrpcpp::InvalidParamsException("Parameter 'id' is missing", request->id());
|
||||
checkParams(request, {"id"});
|
||||
|
||||
return request->params().get<std::string>("id");
|
||||
}
|
||||
|
@ -517,6 +539,8 @@ void StreamControlRequest::execute(const jsonrpcpp::request_ptr& request, AuthIn
|
|||
// Response: {"id":4,"jsonrpc":"2.0","result":{"id":"Spotify"}}
|
||||
// clang-format on
|
||||
|
||||
checkParams(request, {"id", "command"});
|
||||
|
||||
std::ignore = authinfo;
|
||||
LOG(INFO, LOG_TAG) << "Stream.Control id: " << request->params().get<std::string>("id") << ", command: " << request->params().get("command")
|
||||
<< ", params: " << (request->params().has("params") ? request->params().get("params") : "") << "\n";
|
||||
|
@ -524,9 +548,6 @@ void StreamControlRequest::execute(const jsonrpcpp::request_ptr& request, AuthIn
|
|||
// Find stream
|
||||
PcmStreamPtr stream = getStream(getStreamManager(), request);
|
||||
|
||||
if (!request->params().has("command"))
|
||||
throw jsonrpcpp::InvalidParamsException("Parameter 'commmand' is missing", request->id());
|
||||
|
||||
auto command = request->params().get<std::string>("command");
|
||||
|
||||
auto handle_response = [request, on_response, command](const snapcast::ErrorCode& ec)
|
||||
|
@ -595,6 +616,8 @@ StreamSetPropertyRequest::StreamSetPropertyRequest(const Server& server) : Strea
|
|||
|
||||
void StreamSetPropertyRequest::execute(const jsonrpcpp::request_ptr& request, AuthInfo& authinfo, const OnResponse& on_response)
|
||||
{
|
||||
checkParams(request, {"property", "value", "id"});
|
||||
|
||||
LOG(INFO, LOG_TAG) << "Stream.SetProperty id: " << request->params().get<std::string>("id") << ", property: " << request->params().get("property")
|
||||
<< ", value: " << request->params().get("value") << "\n";
|
||||
|
||||
|
@ -603,12 +626,6 @@ void StreamSetPropertyRequest::execute(const jsonrpcpp::request_ptr& request, Au
|
|||
std::string streamId = getStreamId(request);
|
||||
PcmStreamPtr stream = getStream(getStreamManager(), request);
|
||||
|
||||
if (!request->params().has("property"))
|
||||
throw jsonrpcpp::InvalidParamsException("Parameter 'property' is missing", request->id());
|
||||
|
||||
if (!request->params().has("value"))
|
||||
throw jsonrpcpp::InvalidParamsException("Parameter 'value' is missing", request->id());
|
||||
|
||||
auto name = request->params().get<std::string>("property");
|
||||
auto value = request->params().get("value");
|
||||
LOG(INFO, LOG_TAG) << "Stream '" << streamId << "' set property: " << name << " = " << value << "\n";
|
||||
|
@ -673,6 +690,8 @@ void StreamAddRequest::execute(const jsonrpcpp::request_ptr& request, AuthInfo&
|
|||
// Response: {"id":4,"jsonrpc":"2.0","result":{"id":"Spotify"}}
|
||||
// clang-format on
|
||||
|
||||
checkParams(request, {"streamUri"});
|
||||
|
||||
std::ignore = authinfo;
|
||||
LOG(INFO, LOG_TAG) << "Stream.AddStream(" << request->params().get("streamUri") << ")\n";
|
||||
|
||||
|
@ -702,6 +721,7 @@ void StreamRemoveRequest::execute(const jsonrpcpp::request_ptr& request, AuthInf
|
|||
// Request: {"id":4,"jsonrpc":"2.0","method":"Stream.RemoveStream","params":{"id":"Spotify"}}
|
||||
// Response: {"id":4,"jsonrpc":"2.0","result":{"id":"Spotify"}}
|
||||
// clang-format on
|
||||
checkParams(request, {"id"});
|
||||
|
||||
std::ignore = authinfo;
|
||||
LOG(INFO, LOG_TAG) << "Stream.RemoveStream(" << request->params().get("id") << ")\n";
|
||||
|
@ -780,6 +800,8 @@ void ServerDeleteClientRequest::execute(const jsonrpcpp::request_ptr& request, A
|
|||
// Notification: {"jsonrpc":"2.0","method":"Server.OnUpdate","params":{"server":{"groups":[{"clients":[{"config":{"instance":2,"latency":6,"name":"123 456","volume":{"muted":false,"percent":48}},"connected":true,"host":{"arch":"x86_64","ip":"127.0.0.1","mac":"00:21:6a:7d:74:fc","name":"T400","os":"Linux Mint 17.3 Rosa"},"id":"00:21:6a:7d:74:fc#2","lastSeen":{"sec":1488025751,"usec":654777},"snapclient":{"name":"Snapclient","protocolVersion":2,"version":"0.10.0"}}],"id":"4dcc4e3b-c699-a04b-7f0c-8260d23c43e1","muted":false,"name":"","stream_id":"stream 2"}],"server":{"host":{"arch":"x86_64","ip":"","mac":"","name":"T400","os":"Linux Mint 17.3 Rosa"},"snapserver":{"controlProtocolVersion":1,"name":"Snapserver","protocolVersion":1,"version":"0.10.0"}},"streams":[{"id":"stream 1","status":"idle","uri":{"fragment":"","host":"","path":"/tmp/snapfifo","query":{"chunk_ms":"20","codec":"flac","name":"stream 1","sampleformat":"48000:16:2"},"raw":"pipe:///tmp/snapfifo?name=stream 1","scheme":"pipe"}},{"id":"stream 2","status":"idle","uri":{"fragment":"","host":"","path":"/tmp/snapfifo","query":{"chunk_ms":"20","codec":"flac","name":"stream 2","sampleformat":"48000:16:2"},"raw":"pipe:///tmp/snapfifo?name=stream 2","scheme":"pipe"}}]}}}
|
||||
// clang-format on
|
||||
|
||||
checkParams(request, {"id"});
|
||||
|
||||
std::ignore = authinfo;
|
||||
ClientInfoPtr clientInfo = Config::instance().getClientInfo(request->params().get<std::string>("id"));
|
||||
if (clientInfo == nullptr)
|
||||
|
@ -810,10 +832,7 @@ void ServerAuthenticateRequest::execute(const jsonrpcpp::request_ptr& request, A
|
|||
// Response: {"id":8,"jsonrpc":"2.0","result":"ok"}
|
||||
// clang-format on
|
||||
|
||||
if (!request->params().has("scheme"))
|
||||
throw jsonrpcpp::InvalidParamsException("Parameter 'scheme' is missing", request->id());
|
||||
if (!request->params().has("param"))
|
||||
throw jsonrpcpp::InvalidParamsException("Parameter 'param' is missing", request->id());
|
||||
checkParams(request, {"scheme", "param"});
|
||||
|
||||
auto scheme = request->params().get<std::string>("scheme");
|
||||
auto param = request->params().get<std::string>("param");
|
||||
|
@ -841,10 +860,8 @@ void ServerGetTokenRequest::execute(const jsonrpcpp::request_ptr& request, AuthI
|
|||
// Request: {"id":8,"jsonrpc":"2.0","method":"Server.GetToken","params":{"username":"Badaix","password":"secret"}}
|
||||
// Response: {"id":8,"jsonrpc":"2.0","result":{"token":"<token>"}}
|
||||
// clang-format on
|
||||
if (!request->params().has("username"))
|
||||
throw jsonrpcpp::InvalidParamsException("Parameter 'username' is missing", request->id());
|
||||
if (!request->params().has("password"))
|
||||
throw jsonrpcpp::InvalidParamsException("Parameter 'password' is missing", request->id());
|
||||
|
||||
checkParams(request, {"username", "password"});
|
||||
|
||||
auto username = request->params().get<std::string>("username");
|
||||
auto password = request->params().get<std::string>("password");
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
_( )/ ___) / \ ( ( \( _ \( _ \ / __)( ) ( )
|
||||
/ \) \\___ \( O )/ / ) / ) __/( (__(_ _)(_ _)
|
||||
\____/(____/ \__/ \_)__)(__\_)(__) \___)(_) (_)
|
||||
version 1.4.0
|
||||
version 1.4.1
|
||||
https://github.com/badaix/jsonrpcpp
|
||||
|
||||
This file is part of jsonrpc++
|
||||
Copyright (C) 2017-2024 Johannes Pohl
|
||||
Copyright (C) 2017-2025 Johannes Pohl
|
||||
|
||||
This software may be modified and distributed under the terms
|
||||
of the MIT license. See the LICENSE file for details.
|
||||
|
@ -765,7 +765,9 @@ inline bool Parameter::has(const std::string& key) const
|
|||
|
||||
inline Json Parameter::get(const std::string& key) const
|
||||
{
|
||||
return param_map.at(key);
|
||||
if (has(key))
|
||||
return param_map.at(key);
|
||||
throw RpcException("Parameter '" + key + "' not found");
|
||||
}
|
||||
|
||||
inline bool Parameter::has(size_t idx) const
|
||||
|
|
|
@ -157,7 +157,8 @@ void Server::processRequest(const jsonrpcpp::request_ptr& request, AuthInfo& aut
|
|||
else
|
||||
{
|
||||
LOG(ERROR, LOG_TAG) << "Method not found: " << request->method() << "\n";
|
||||
throw jsonrpcpp::MethodNotFoundException(request->id());
|
||||
auto response = std::make_shared<jsonrpcpp::MethodNotFoundException>(request->id());
|
||||
on_response(std::move(response), nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue