From 948d168790aa5580e1bef8ff15e01b276925ccc6 Mon Sep 17 00:00:00 2001 From: Andrzej Rybczak Date: Sun, 20 Dec 2020 16:14:47 +0100 Subject: [PATCH] Handle listallinfo failures more gracefully --- src/helpers.cpp | 34 --------------------------------- src/helpers.h | 2 -- src/mpdpp.h | 36 ++++++++++++++++++++--------------- src/screens/media_library.cpp | 26 +++++++++++++++++++++++-- src/screens/search_engine.cpp | 2 +- 5 files changed, 46 insertions(+), 54 deletions(-) diff --git a/src/helpers.cpp b/src/helpers.cpp index cdff5517..a8b9ec05 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -42,40 +42,6 @@ const MPD::Song *currentSong(const BaseScreen *screen) 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 &playlist) { selectCurrentIfNoneSelected(playlist); diff --git a/src/helpers.h b/src/helpers.h index df05103a..dffb827c 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -534,8 +534,6 @@ bool addSongToPlaylist(const MPD::Song &s, bool play, int position = -1); const MPD::Song *currentSong(const BaseScreen *screen); -MPD::SongIterator getDatabaseIterator(MPD::Connection &mpd); - std::string timeFormat(const char *format, time_t t); std::string Timestamp(time_t t); diff --git a/src/mpdpp.h b/src/mpdpp.h index d13eb9c4..ce23c835 100644 --- a/src/mpdpp.h +++ b/src/mpdpp.h @@ -38,36 +38,42 @@ void checkConnectionErrors(mpd_connection *conn); enum PlayerState { psUnknown, psStop, psPlay, psPause }; enum ReplayGainMode { rgmOff, rgmTrack, rgmAlbum }; -struct ClientError: public std::exception +struct Error: public std::exception { - ClientError(mpd_error code_, std::string msg, bool clearable_) - : m_code(code_), m_msg(msg), m_clearable(clearable_) { } - virtual ~ClientError() noexcept { } - + Error(std::string msg, bool clearable_) + : m_msg(msg), m_clearable(clearable_) { } + virtual ~Error() noexcept { } + virtual const char *what() const noexcept { return m_msg.c_str(); } - mpd_error code() const { return m_code; } bool clearable() const { return m_clearable; } - + private: - mpd_error m_code; std::string m_msg; 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_) - : m_code(code_), m_msg(msg), m_clearable(clearable_) { } + : Error(msg, clearable_), m_code(code_) { } virtual ~ServerError() noexcept { } - virtual const char *what() const noexcept { return m_msg.c_str(); } mpd_server_error code() const { return m_code; } - bool clearable() const { return m_clearable; } - + private: mpd_server_error m_code; - std::string m_msg; - bool m_clearable; }; struct Statistics diff --git a/src/screens/media_library.cpp b/src/screens/media_library.cpp index 8c13cedd..558458d0 100644 --- a/src/screens/media_library.cpp +++ b/src/screens/media_library.cpp @@ -302,7 +302,18 @@ void MediaLibrary::update() m_albums_update_request = false; sunfilter_albums.set(ReapplyFilter::Yes, true); std::map, 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; unsigned idx = 0; @@ -349,7 +360,18 @@ void MediaLibrary::update() std::map tags; 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; unsigned idx = 0; diff --git a/src/screens/search_engine.cpp b/src/screens/search_engine.cpp index e18702c4..f0e20e0b 100644 --- a/src/screens/search_engine.cpp +++ b/src/screens/search_engine.cpp @@ -500,7 +500,7 @@ void SearchEngine::Search() input_song_iterator s, end; if (Config.search_in_db) { - s = input_song_iterator(getDatabaseIterator(Mpd)); + s = input_song_iterator(Mpd.GetDirectoryRecursive("/")); end = input_song_iterator(MPD::SongIterator()); } else