Handle listallinfo failures more gracefully
This commit is contained in:
@@ -42,40 +42,6 @@ const MPD::Song *currentSong(const BaseScreen *screen)
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MPD::SongIterator getDatabaseIterator(MPD::Connection &mpd)
|
|
||||||
{
|
|
||||||
MPD::SongIterator result;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
result = mpd.GetDirectoryRecursive("/");
|
|
||||||
}
|
|
||||||
catch (MPD::ClientError &e)
|
|
||||||
{
|
|
||||||
if (e.code() == MPD_ERROR_CLOSED)
|
|
||||||
{
|
|
||||||
// If we can't get the database, display appropriate
|
|
||||||
// error message and reconnect with the MPD server.
|
|
||||||
Statusbar::print("Unable to fetch the data, increase max_output_buffer_size in your MPD configuration file");
|
|
||||||
mpd.Disconnect();
|
|
||||||
mpd.Connect();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
catch (MPD::ServerError &e)
|
|
||||||
{
|
|
||||||
// mopidy blacklists 'listallinfo' command by default and throws server
|
|
||||||
// error when it receives it. Work around that to prevent ncmpcpp from
|
|
||||||
// continuously retrying to send the command and looping.
|
|
||||||
if (strstr(e.what(), "listallinfo") != nullptr
|
|
||||||
&& strstr(e.what(), "disabled") != nullptr)
|
|
||||||
Statusbar::print("Unable to fetch the data, server refused to process 'listallinfo' command");
|
|
||||||
else
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void deleteSelectedSongsFromPlaylist(NC::Menu<MPD::Song> &playlist)
|
void deleteSelectedSongsFromPlaylist(NC::Menu<MPD::Song> &playlist)
|
||||||
{
|
{
|
||||||
selectCurrentIfNoneSelected(playlist);
|
selectCurrentIfNoneSelected(playlist);
|
||||||
|
|||||||
@@ -534,8 +534,6 @@ bool addSongToPlaylist(const MPD::Song &s, bool play, int position = -1);
|
|||||||
|
|
||||||
const MPD::Song *currentSong(const BaseScreen *screen);
|
const MPD::Song *currentSong(const BaseScreen *screen);
|
||||||
|
|
||||||
MPD::SongIterator getDatabaseIterator(MPD::Connection &mpd);
|
|
||||||
|
|
||||||
std::string timeFormat(const char *format, time_t t);
|
std::string timeFormat(const char *format, time_t t);
|
||||||
|
|
||||||
std::string Timestamp(time_t t);
|
std::string Timestamp(time_t t);
|
||||||
|
|||||||
36
src/mpdpp.h
36
src/mpdpp.h
@@ -38,36 +38,42 @@ void checkConnectionErrors(mpd_connection *conn);
|
|||||||
enum PlayerState { psUnknown, psStop, psPlay, psPause };
|
enum PlayerState { psUnknown, psStop, psPlay, psPause };
|
||||||
enum ReplayGainMode { rgmOff, rgmTrack, rgmAlbum };
|
enum ReplayGainMode { rgmOff, rgmTrack, rgmAlbum };
|
||||||
|
|
||||||
struct ClientError: public std::exception
|
struct Error: public std::exception
|
||||||
{
|
{
|
||||||
ClientError(mpd_error code_, std::string msg, bool clearable_)
|
Error(std::string msg, bool clearable_)
|
||||||
: m_code(code_), m_msg(msg), m_clearable(clearable_) { }
|
: m_msg(msg), m_clearable(clearable_) { }
|
||||||
virtual ~ClientError() noexcept { }
|
virtual ~Error() noexcept { }
|
||||||
|
|
||||||
virtual const char *what() const noexcept { return m_msg.c_str(); }
|
virtual const char *what() const noexcept { return m_msg.c_str(); }
|
||||||
mpd_error code() const { return m_code; }
|
|
||||||
bool clearable() const { return m_clearable; }
|
bool clearable() const { return m_clearable; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mpd_error m_code;
|
|
||||||
std::string m_msg;
|
std::string m_msg;
|
||||||
bool m_clearable;
|
bool m_clearable;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ServerError: public std::exception
|
struct ClientError: public Error
|
||||||
|
{
|
||||||
|
ClientError(mpd_error code_, std::string msg, bool clearable_)
|
||||||
|
: Error(msg, clearable_), m_code(code_) { }
|
||||||
|
virtual ~ClientError() noexcept { }
|
||||||
|
|
||||||
|
mpd_error code() const { return m_code; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
mpd_error m_code;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ServerError: public Error
|
||||||
{
|
{
|
||||||
ServerError(mpd_server_error code_, std::string msg, bool clearable_)
|
ServerError(mpd_server_error code_, std::string msg, bool clearable_)
|
||||||
: m_code(code_), m_msg(msg), m_clearable(clearable_) { }
|
: Error(msg, clearable_), m_code(code_) { }
|
||||||
virtual ~ServerError() noexcept { }
|
virtual ~ServerError() noexcept { }
|
||||||
|
|
||||||
virtual const char *what() const noexcept { return m_msg.c_str(); }
|
|
||||||
mpd_server_error code() const { return m_code; }
|
mpd_server_error code() const { return m_code; }
|
||||||
bool clearable() const { return m_clearable; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mpd_server_error m_code;
|
mpd_server_error m_code;
|
||||||
std::string m_msg;
|
|
||||||
bool m_clearable;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Statistics
|
struct Statistics
|
||||||
|
|||||||
@@ -302,7 +302,18 @@ void MediaLibrary::update()
|
|||||||
m_albums_update_request = false;
|
m_albums_update_request = false;
|
||||||
sunfilter_albums.set(ReapplyFilter::Yes, true);
|
sunfilter_albums.set(ReapplyFilter::Yes, true);
|
||||||
std::map<std::tuple<std::string, std::string, std::string>, time_t> albums;
|
std::map<std::tuple<std::string, std::string, std::string>, time_t> albums;
|
||||||
for (MPD::SongIterator s = getDatabaseIterator(Mpd), end; s != end; ++s)
|
MPD::SongIterator s, end;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
s = Mpd.GetDirectoryRecursive("/");
|
||||||
|
}
|
||||||
|
catch (MPD::Error &e)
|
||||||
|
{
|
||||||
|
// If there was a problem, fall back to a different column mode.
|
||||||
|
toggleColumnsMode();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
for (; s != end; ++s)
|
||||||
{
|
{
|
||||||
std::string tag;
|
std::string tag;
|
||||||
unsigned idx = 0;
|
unsigned idx = 0;
|
||||||
@@ -349,7 +360,18 @@ void MediaLibrary::update()
|
|||||||
std::map<std::string, time_t> tags;
|
std::map<std::string, time_t> tags;
|
||||||
if (Config.media_library_sort_by_mtime)
|
if (Config.media_library_sort_by_mtime)
|
||||||
{
|
{
|
||||||
for (MPD::SongIterator s = getDatabaseIterator(Mpd), end; s != end; ++s)
|
MPD::SongIterator s, end;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
s = Mpd.GetDirectoryRecursive("/");
|
||||||
|
}
|
||||||
|
catch (MPD::Error &e)
|
||||||
|
{
|
||||||
|
// If there was a problem, fall back to a different sorting mode.
|
||||||
|
toggleSortMode();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
for (; s != end; ++s)
|
||||||
{
|
{
|
||||||
std::string tag;
|
std::string tag;
|
||||||
unsigned idx = 0;
|
unsigned idx = 0;
|
||||||
|
|||||||
@@ -500,7 +500,7 @@ void SearchEngine::Search()
|
|||||||
input_song_iterator s, end;
|
input_song_iterator s, end;
|
||||||
if (Config.search_in_db)
|
if (Config.search_in_db)
|
||||||
{
|
{
|
||||||
s = input_song_iterator(getDatabaseIterator(Mpd));
|
s = input_song_iterator(Mpd.GetDirectoryRecursive("/"));
|
||||||
end = input_song_iterator(MPD::SongIterator());
|
end = input_song_iterator(MPD::SongIterator());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user