input/tidal: parse subStatus in error responses

This commit is contained in:
Max Kellermann 2018-01-24 12:26:12 +01:00
parent 2e1481f49d
commit 4398101706
3 changed files with 37 additions and 4 deletions

View File

@ -33,15 +33,25 @@ class TidalError : public std::runtime_error {
*/ */
unsigned status; unsigned status;
/**
* The Tidal-specific "subStatus". 0 if none was found in the
* JSON response.
*/
unsigned sub_status;
public: public:
template<typename W> template<typename W>
TidalError(unsigned _status, W &&_what) noexcept TidalError(unsigned _status, unsigned _sub_status, W &&_what) noexcept
:std::runtime_error(std::forward<W>(_what)), :std::runtime_error(std::forward<W>(_what)),
status(_status) {} status(_status), sub_status(_sub_status) {}
unsigned GetStatus() const noexcept { unsigned GetStatus() const noexcept {
return status; return status;
} }
unsigned GetSubStatus() const noexcept {
return sub_status;
}
}; };
#endif #endif

View File

@ -28,7 +28,7 @@ using Wrapper = Yajl::CallbacksWrapper<TidalErrorParser>;
static constexpr yajl_callbacks tidal_error_parser_callbacks = { static constexpr yajl_callbacks tidal_error_parser_callbacks = {
nullptr, nullptr,
nullptr, nullptr,
nullptr, Wrapper::Integer,
nullptr, nullptr,
nullptr, nullptr,
Wrapper::String, Wrapper::String,
@ -62,7 +62,23 @@ TidalErrorParser::OnEnd()
else else
snprintf(what, sizeof(what), "Status %u from Tidal", status); snprintf(what, sizeof(what), "Status %u from Tidal", status);
throw TidalError(status, what); throw TidalError(status, sub_status, what);
}
inline bool
TidalErrorParser::Integer(long long value) noexcept
{
switch (state) {
case State::NONE:
case State::USER_MESSAGE:
break;
case State::SUB_STATUS:
sub_status = value;
break;
}
return true;
} }
inline bool inline bool
@ -70,6 +86,7 @@ TidalErrorParser::String(StringView value) noexcept
{ {
switch (state) { switch (state) {
case State::NONE: case State::NONE:
case State::SUB_STATUS:
break; break;
case State::USER_MESSAGE: case State::USER_MESSAGE:
@ -85,6 +102,8 @@ TidalErrorParser::MapKey(StringView value) noexcept
{ {
if (value.Equals("userMessage")) if (value.Equals("userMessage"))
state = State::USER_MESSAGE; state = State::USER_MESSAGE;
else if (value.Equals("subStatus"))
state = State::SUB_STATUS;
else else
state = State::NONE; state = State::NONE;

View File

@ -39,8 +39,11 @@ class TidalErrorParser final : public YajlResponseParser {
enum class State { enum class State {
NONE, NONE,
USER_MESSAGE, USER_MESSAGE,
SUB_STATUS,
} state = State::NONE; } state = State::NONE;
unsigned sub_status = 0;
std::string message; std::string message;
public: public:
@ -57,6 +60,7 @@ protected:
public: public:
/* yajl callbacks */ /* yajl callbacks */
bool Integer(long long value) noexcept;
bool String(StringView value) noexcept; bool String(StringView value) noexcept;
bool MapKey(StringView value) noexcept; bool MapKey(StringView value) noexcept;
bool EndMap() noexcept; bool EndMap() noexcept;