Subsonic API: better parameter/error handling

This commit is contained in:
emeric
2019-04-07 17:23:46 +02:00
parent 9ebea81104
commit b4103999a7
3 changed files with 58 additions and 34 deletions
+31 -31
View File
@@ -160,20 +160,29 @@ getParameterAs(const Wt::Http::ParameterMap& parameterMap, const std::string& pa
return it->second.front(); return it->second.front();
} }
Id template<>
getParameterAsId(const Wt::Http::ParameterMap& parameterMap, const std::string& param) boost::optional<Id>
getParameterAs(const Wt::Http::ParameterMap& parameterMap, const std::string& param)
{ {
boost::optional<Id> res;
auto idParam {getParameterAs<std::string>(parameterMap, "id")}; auto idParam {getParameterAs<std::string>(parameterMap, "id")};
if (!idParam) if (!idParam)
throw Error {Error::Code::RequiredParameterMissing}; return res;
auto id {IdFromString(*idParam)}; return IdFromString(*idParam);
if (!id)
throw Error {"Bad id"};
return *id;
} }
template<typename T>
T
getMandatoryParameterAs(const Wt::Http::ParameterMap& parameterMap, const std::string& param)
{
auto res {getParameterAs<T>(parameterMap, param)};
if (!res)
throw Error {Error::Code::RequiredParameterMissing};
return *res;
}
struct ClientInfo struct ClientInfo
{ {
@@ -601,7 +610,7 @@ handleGetAlbumListRequestCommon(const Wt::Http::ParameterMap& request, Database:
releases = Database::Release::getAll(db.getSession(), offset, size); releases = Database::Release::getAll(db.getSession(), offset, size);
} }
else else
throw Error {"Unsupported request"}; throw Error {Error::CustomType::NotImplemented};
Response response {Response::createOkResponse()}; Response response {Response::createOkResponse()};
Response::Node& albumListNode {response.createNode(id3 ? "albumList2" : "albumList")}; Response::Node& albumListNode {response.createNode(id3 ? "albumList2" : "albumList")};
@@ -628,10 +637,10 @@ Response
handleGetAlbumRequest(const Wt::Http::ParameterMap& request, Database::Handler& db) handleGetAlbumRequest(const Wt::Http::ParameterMap& request, Database::Handler& db)
{ {
// Mandatory params // Mandatory params
Id id {getParameterAsId(request, "id")}; Id id {getMandatoryParameterAs<Id>(request, "id")};
if (id.type != Id::Type::Release) if (id.type != Id::Type::Release)
throw Error {"Unexpected id type"}; throw Error {Error::CustomType::BadId};
Wt::Dbo::Transaction transaction {db.getSession()}; Wt::Dbo::Transaction transaction {db.getSession()};
@@ -655,10 +664,10 @@ Response
handleGetArtistRequest(const Wt::Http::ParameterMap& request, Database::Handler& db) handleGetArtistRequest(const Wt::Http::ParameterMap& request, Database::Handler& db)
{ {
// Mandatory params // Mandatory params
Id id {getParameterAsId(request, "id")}; Id id {getMandatoryParameterAs<Id>(request, "id")};
if (id.type != Id::Type::Artist) if (id.type != Id::Type::Artist)
throw Error {"Unexpected id type"}; throw Error {Error::CustomType::BadId};
Wt::Dbo::Transaction transaction {db.getSession()}; Wt::Dbo::Transaction transaction {db.getSession()};
@@ -701,7 +710,7 @@ Response
handleGetMusicDirectoryRequest(const Wt::Http::ParameterMap& request, Database::Handler& db) handleGetMusicDirectoryRequest(const Wt::Http::ParameterMap& request, Database::Handler& db)
{ {
// Mandatory params // Mandatory params
Id id {getParameterAsId(request, "id")}; Id id {getMandatoryParameterAs<Id>(request, "id")};
Response response {Response::createOkResponse()}; Response response {Response::createOkResponse()};
Response::Node& directoryNode {response.createNode("directory")}; Response::Node& directoryNode {response.createNode("directory")};
@@ -758,7 +767,7 @@ handleGetMusicDirectoryRequest(const Wt::Http::ParameterMap& request, Database::
} }
default: default:
throw Error {"Unexpected id type"}; throw Error {Error::CustomType::BadId};
} }
return response; return response;
@@ -820,28 +829,19 @@ handleGetIndexesRequest(const Wt::Http::ParameterMap& request, Database::Handler
Response Response
handleGetStarredRequest(const Wt::Http::ParameterMap& request, Database::Handler& db) handleGetStarredRequest(const Wt::Http::ParameterMap& request, Database::Handler& db)
{ {
Response response {Response::createOkResponse()}; throw Error{Error::CustomType::NotImplemented};
response.createNode("starred");
return response;
} }
Response Response
handleGetStarred2Request(const Wt::Http::ParameterMap& request, Database::Handler& db) handleGetStarred2Request(const Wt::Http::ParameterMap& request, Database::Handler& db)
{ {
Response response {Response::createOkResponse()}; throw Error{Error::CustomType::NotImplemented};
response.createNode("starred2");
return response;
} }
Response Response
handleGetPlaylistsRequest(const Wt::Http::ParameterMap& request, Database::Handler& db) handleGetPlaylistsRequest(const Wt::Http::ParameterMap& request, Database::Handler& db)
{ {
Response response {Response::createOkResponse()}; throw Error{Error::CustomType::NotImplemented};
response.createNode("playlists");
return response;
} }
Response Response
@@ -942,7 +942,7 @@ std::shared_ptr<Av::Transcoder>
createTranscoder(const Wt::Http::ParameterMap& request, Database::Handler& db) createTranscoder(const Wt::Http::ParameterMap& request, Database::Handler& db)
{ {
// Mandatory params // Mandatory params
Id id {getParameterAsId(request, "id")}; Id id {getMandatoryParameterAs<Id>(request, "id")};
// Optional params // Optional params
std::size_t maxBitRate {getParameterAs<std::size_t>(request, "maxBitRate").get_value_or(128)}; std::size_t maxBitRate {getParameterAs<std::size_t>(request, "maxBitRate").get_value_or(128)};
@@ -987,7 +987,7 @@ handleStream(const Wt::Http::Request& request, Database::Handler& db, Wt::Http::
} }
if (!transcoder) if (!transcoder)
throw Error {"transcoding failed"}; throw Error {Error::CustomType::InternalError};
if (!transcoder->isComplete()) if (!transcoder->isComplete())
{ {
@@ -1018,7 +1018,7 @@ void
handleGetCoverArt(const Wt::Http::Request& request, Database::Handler& db, Wt::Http::Response& response) handleGetCoverArt(const Wt::Http::Request& request, Database::Handler& db, Wt::Http::Response& response)
{ {
// Mandatory params // Mandatory params
Id id {getParameterAsId(request.getParameterMap(), "id")}; Id id {getMandatoryParameterAs<Id>(request.getParameterMap(), "id")};
auto size {getParameterAs<std::size_t>(request.getParameterMap(), "size")}; auto size {getParameterAs<std::size_t>(request.getParameterMap(), "size")};
if (!size) if (!size)
@@ -1036,7 +1036,7 @@ handleGetCoverArt(const Wt::Http::Request& request, Database::Handler& db, Wt::H
cover = getServices().coverArtGrabber->getFromRelease(db.getSession(), id.id, Image::Format::JPEG, *size); cover = getServices().coverArtGrabber->getFromRelease(db.getSession(), id.id, Image::Format::JPEG, *size);
break; break;
default: default:
throw Error {"Unexpected id type"}; throw Error {Error::CustomType::BadId};
} }
response.setMimeType( Image::format_to_mimeType(Image::Format::JPEG) ); response.setMimeType( Image::format_to_mimeType(Image::Format::JPEG) );
+19 -2
View File
@@ -66,15 +66,32 @@ ErrorCodeToString(Error::Code error)
} }
} }
static
const char*
CustomTypeToString(Error::CustomType type)
{
switch (type)
{
case Error::CustomType::BadId:
return "Bad id";
case Error::CustomType::NotImplemented:
return "Not implemented";
case Error::CustomType::InternalError:
return "Internal error";
default:
return "Unknown custom error";
}
}
Error::Error(Code code) Error::Error(Code code)
: _code {code}, : _code {code},
_message {ErrorCodeToString(code)} _message {ErrorCodeToString(code)}
{ {
} }
Error::Error(const std::string& message) Error::Error(Error::CustomType type)
: _code {Code::Generic}, : _code {Code::Generic},
_message {message} _message {CustomTypeToString(type)}
{ {
} }
+8 -1
View File
@@ -46,8 +46,15 @@ class Error
RequestedDataNotFound = 70, RequestedDataNotFound = 70,
}; };
enum class CustomType
{
BadId,
NotImplemented,
InternalError,
};
Error(Code code); Error(Code code);
Error(const std::string& message); Error(CustomType customType);
Code getCode() const { return _code; } Code getCode() const { return _code; }
const std::string& getMessage() const { return _message; } const std::string& getMessage() const { return _message; }