Subsonic API: better parameter/error handling
This commit is contained in:
@@ -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) );
|
||||||
|
|||||||
@@ -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)}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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; }
|
||||||
|
|||||||
Reference in New Issue
Block a user