From 914df18bf93369d279fff85f87c4ac8524f32540 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Tue, 19 Dec 2017 10:56:23 +0100
Subject: [PATCH] Main, ...: catch any exception, not just std::runtime_error

---
 src/Instance.cxx                              |  4 +--
 src/Listen.cxx                                |  6 ++--
 src/Main.cxx                                  |  2 +-
 src/PlaylistSave.cxx                          |  6 ++--
 src/SongFilter.cxx                            |  4 +--
 src/SongUpdate.cxx                            |  4 +--
 src/Stats.cxx                                 |  4 +--
 src/TagFile.cxx                               |  6 ++--
 src/TagStream.cxx                             |  4 +--
 src/command/StorageCommands.cxx               |  2 +-
 src/db/plugins/ProxyDatabasePlugin.cxx        | 12 +++----
 src/db/update/Archive.cxx                     |  6 ++--
 src/db/update/Container.cxx                   |  4 +--
 src/db/update/ExcludeList.cxx                 |  8 ++---
 src/db/update/InotifyUpdate.cxx               | 16 +++++-----
 src/db/update/UpdateIO.cxx                    | 12 +++----
 src/db/update/Walk.cxx                        |  4 +--
 src/decoder/Bridge.cxx                        |  4 +--
 src/decoder/DecoderAPI.cxx                    |  4 +--
 src/decoder/DecoderThread.cxx                 |  2 +-
 .../plugins/AudiofileDecoderPlugin.cxx        |  6 ++--
 src/decoder/plugins/DsdLib.cxx                |  4 +--
 src/decoder/plugins/FaadDecoderPlugin.cxx     |  6 ++--
 src/decoder/plugins/FfmpegDecoderPlugin.cxx   |  8 ++---
 src/decoder/plugins/FfmpegIo.cxx              |  4 +--
 src/decoder/plugins/FlacCommon.cxx            |  6 ++--
 src/decoder/plugins/FlacDecoderPlugin.cxx     |  2 +-
 src/decoder/plugins/FlacIOHandle.cxx          |  6 ++--
 src/decoder/plugins/FlacInput.cxx             |  6 ++--
 src/decoder/plugins/MadDecoderPlugin.cxx      |  2 +-
 src/decoder/plugins/MpcdecDecoderPlugin.cxx   |  4 +--
 src/decoder/plugins/OggDecoder.cxx            |  4 +--
 src/decoder/plugins/OpusDecoderPlugin.cxx     |  4 +--
 src/decoder/plugins/PcmDecoderPlugin.cxx      | 14 ++++-----
 src/decoder/plugins/SndfileDecoderPlugin.cxx  |  6 ++--
 src/decoder/plugins/VorbisDecoderPlugin.cxx   |  4 +--
 src/decoder/plugins/WavpackDecoderPlugin.cxx  |  4 +--
 src/event/ServerSocket.cxx                    |  4 +--
 src/filter/plugins/ReplayGainFilterPlugin.cxx |  7 +++--
 src/fs/AllocatedPath.cxx                      |  6 ++--
 src/fs/CheckFile.cxx                          |  4 +--
 src/fs/Path.cxx                               |  4 +--
 src/input/Init.cxx                            |  2 +-
 src/input/TextInputStream.cxx                 |  4 +--
 src/lib/icu/CaseFold.cxx                      |  3 +-
 src/lib/icu/Collate.cxx                       |  8 ++---
 src/lib/xiph/OggFind.cxx                      |  4 +--
 src/mixer/MixerAll.cxx                        |  8 ++---
 src/mixer/plugins/AlsaMixerPlugin.cxx         |  2 +-
 src/neighbor/plugins/UpnpNeighborPlugin.cxx   |  4 +--
 src/output/Control.cxx                        |  5 +--
 src/output/Filtered.cxx                       | 14 ++++-----
 src/output/Init.cxx                           |  8 ++---
 src/output/MultipleOutputs.cxx                |  2 +-
 src/output/Thread.cxx                         | 31 ++++++++++---------
 src/output/plugins/AlsaOutputPlugin.cxx       |  2 +-
 src/output/plugins/FifoOutputPlugin.cxx       |  4 +--
 src/output/plugins/PulseOutputPlugin.cxx      |  2 +-
 src/output/plugins/RecorderOutputPlugin.cxx   | 22 ++++++-------
 src/output/plugins/ShoutOutputPlugin.cxx      |  2 +-
 .../plugins/httpd/HttpdOutputPlugin.cxx       |  6 ++--
 src/player/Thread.cxx                         | 14 ++++-----
 src/playlist/PlaylistRegistry.cxx             |  6 ++--
 src/playlist/PlaylistSong.cxx                 |  4 +--
 src/playlist/PlaylistStream.cxx               | 14 ++++-----
 src/queue/PlaylistUpdate.cxx                  |  4 +--
 src/queue/QueueSave.cxx                       |  6 ++--
 src/sticker/SongSticker.cxx                   |  4 +--
 src/storage/CompositeStorage.cxx              |  2 +-
 src/storage/plugins/CurlStorage.cxx           |  2 +-
 src/storage/plugins/LocalStorage.cxx          |  2 +-
 src/tag/ApeLoader.cxx                         |  5 ++-
 src/tag/Generic.cxx                           |  8 ++---
 src/tag/Id3Load.cxx                           | 21 ++++++-------
 src/tag/Id3Scan.cxx                           |  6 ++--
 test/FakeDecoderAPI.cxx                       |  4 +--
 test/TestIcu.cxx                              |  4 +--
 test/run_inotify.cxx                          |  6 ++--
 test/run_resolver.cxx                         |  6 ++--
 79 files changed, 236 insertions(+), 244 deletions(-)

diff --git a/src/Instance.cxx b/src/Instance.cxx
index d1196cfb8..bd91faccd 100644
--- a/src/Instance.cxx
+++ b/src/Instance.cxx
@@ -32,7 +32,7 @@
 #endif
 #endif
 
-#include <stdexcept>
+#include <exception>
 
 Instance::Instance()
 	:idle_monitor(event_loop, BIND_THIS_METHOD(OnIdle))
@@ -84,7 +84,7 @@ Instance::OnDatabaseSongRemoved(const char *uri)
 	if (sticker_enabled()) {
 		try {
 			sticker_song_delete(uri);
-		} catch (const std::runtime_error &) {
+		} catch (...) {
 		}
 	}
 #endif
diff --git a/src/Listen.cxx b/src/Listen.cxx
index 987737f9f..ae5d9d050 100644
--- a/src/Listen.cxx
+++ b/src/Listen.cxx
@@ -120,7 +120,7 @@ listen_global_init(EventLoop &loop, Partition &partition)
 		do {
 			try {
 				listen_add_config_param(port, param);
-			} catch (const std::runtime_error &e) {
+			} catch (...) {
 				delete listen_socket;
 				std::throw_with_nested(FormatRuntimeError("Failed to listen on %s (line %i)",
 									  param->value.c_str(),
@@ -133,7 +133,7 @@ listen_global_init(EventLoop &loop, Partition &partition)
 
 		try {
 			listen_socket->AddPort(port);
-		} catch (const std::runtime_error &e) {
+		} catch (...) {
 			delete listen_socket;
 			std::throw_with_nested(FormatRuntimeError("Failed to listen on *:%d: ", port));
 		}
@@ -141,7 +141,7 @@ listen_global_init(EventLoop &loop, Partition &partition)
 
 	try {
 		listen_socket->Open();
-	} catch (const std::runtime_error &e) {
+	} catch (...) {
 		delete listen_socket;
 		throw;
 	}
diff --git a/src/Main.cxx b/src/Main.cxx
index f5bc28467..6d9f8d88e 100644
--- a/src/Main.cxx
+++ b/src/Main.cxx
@@ -379,7 +379,7 @@ initialize_decoder_and_player(const ReplayGainConfig &replay_gain_config)
 		try {
 			configured_audio_format = ParseAudioFormat(param->value.c_str(),
 								   true);
-		} catch (const std::runtime_error &) {
+		} catch (...) {
 			std::throw_with_nested(FormatRuntimeError("error parsing line %i",
 								  param->line));
 		}
diff --git a/src/PlaylistSave.cxx b/src/PlaylistSave.cxx
index d3ec30bb2..ba61c7286 100644
--- a/src/PlaylistSave.cxx
+++ b/src/PlaylistSave.cxx
@@ -32,7 +32,7 @@
 #include "fs/io/BufferedOutputStream.hxx"
 #include "util/UriUtil.hxx"
 
-#include <stdexcept>
+#include <exception>
 
 static void
 playlist_print_path(BufferedOutputStream &os, const Path path)
@@ -57,7 +57,7 @@ playlist_print_song(BufferedOutputStream &os, const DetachedSong &song)
 	try {
 		const auto uri_fs = AllocatedPath::FromUTF8Throw(uri_utf8);
 		playlist_print_path(os, uri_fs);
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 	}
 }
 
@@ -76,7 +76,7 @@ playlist_print_uri(BufferedOutputStream &os, const char *uri)
 
 		if (!path.IsNull())
 			playlist_print_path(os, path);
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 	}
 }
 
diff --git a/src/SongFilter.cxx b/src/SongFilter.cxx
index 3bb8894ef..870788479 100644
--- a/src/SongFilter.cxx
+++ b/src/SongFilter.cxx
@@ -30,7 +30,7 @@
 #include "util/UriUtil.hxx"
 #include "lib/icu/CaseFold.hxx"
 
-#include <stdexcept>
+#include <exception>
 
 #include <assert.h>
 #include <stdlib.h>
@@ -190,7 +190,7 @@ ParseTimeStamp(const char *s)
 	try {
 		/* try ISO 8601 */
 		return ParseTimePoint(s, "%FT%TZ");
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 		return std::chrono::system_clock::time_point::min();
 	}
 }
diff --git a/src/SongUpdate.cxx b/src/SongUpdate.cxx
index 6eb76a9bd..99d0f0761 100644
--- a/src/SongUpdate.cxx
+++ b/src/SongUpdate.cxx
@@ -34,7 +34,7 @@
 #include "TagArchive.hxx"
 #endif
 
-#include <stdexcept>
+#include <exception>
 
 #include <assert.h>
 #include <string.h>
@@ -68,7 +68,7 @@ Song::UpdateFile(Storage &storage)
 	StorageFileInfo info;
 	try {
 		info = storage.GetInfo(relative_uri.c_str(), true);
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 		return false;
 	}
 
diff --git a/src/Stats.cxx b/src/Stats.cxx
index c80136f85..df3b78148 100644
--- a/src/Stats.cxx
+++ b/src/Stats.cxx
@@ -77,8 +77,8 @@ stats_update(const Database &db)
 		stats = db.GetStats(selection);
 		stats_validity = StatsValidity::VALID;
 		return true;
-	} catch (const std::runtime_error &e) {
-		LogError(e);
+	} catch (...) {
+		LogError(std::current_exception());
 		stats_validity = StatsValidity::FAILED;
 		return false;
 	}
diff --git a/src/TagFile.cxx b/src/TagFile.cxx
index 6a0c02968..02ac42005 100644
--- a/src/TagFile.cxx
+++ b/src/TagFile.cxx
@@ -29,7 +29,7 @@
 #include "input/LocalOpen.hxx"
 #include "thread/Cond.hxx"
 
-#include <stdexcept>
+#include <exception>
 
 #include <assert.h>
 
@@ -64,13 +64,13 @@ public:
 			try {
 				is = OpenLocalInputStream(path_fs,
 							  mutex, cond);
-			} catch (const std::runtime_error &) {
+			} catch (...) {
 				return false;
 			}
 		} else {
 			try {
 				is->LockRewind();
-			} catch (const std::runtime_error &) {
+			} catch (...) {
 			}
 		}
 
diff --git a/src/TagStream.cxx b/src/TagStream.cxx
index 2d7748529..58cdcb555 100644
--- a/src/TagStream.cxx
+++ b/src/TagStream.cxx
@@ -30,7 +30,7 @@
 #include "thread/Mutex.hxx"
 #include "thread/Cond.hxx"
 
-#include <stdexcept>
+#include <exception>
 
 #include <assert.h>
 
@@ -66,7 +66,7 @@ tag_stream_scan(InputStream &is, const TagHandler &handler, void *ctx)
 				    &handler, ctx](const DecoderPlugin &plugin){
 			try {
 				is.LockRewind();
-			} catch (const std::runtime_error &) {
+			} catch (...) {
 			}
 
 			return CheckDecoderPlugin(plugin, suffix, mime) &&
diff --git a/src/command/StorageCommands.cxx b/src/command/StorageCommands.cxx
index b47c4ab74..e32e51b4c 100644
--- a/src/command/StorageCommands.cxx
+++ b/src/command/StorageCommands.cxx
@@ -68,7 +68,7 @@ handle_listfiles_storage(Response &r, StorageDirectoryReader &reader)
 		StorageFileInfo info;
 		try {
 			info = reader.GetInfo(false);
-		} catch (const std::runtime_error &) {
+		} catch (...) {
 			continue;
 		}
 
diff --git a/src/db/plugins/ProxyDatabasePlugin.cxx b/src/db/plugins/ProxyDatabasePlugin.cxx
index 728363815..8a896c9e6 100644
--- a/src/db/plugins/ProxyDatabasePlugin.cxx
+++ b/src/db/plugins/ProxyDatabasePlugin.cxx
@@ -361,10 +361,10 @@ ProxyDatabase::Open()
 
 	try {
 		Connect();
-	} catch (const std::runtime_error &error) {
+	} catch (...) {
 		/* this error is non-fatal, because this plugin will
 		   attempt to reconnect again automatically */
-		LogError(error);
+		LogError(std::current_exception());
 	}
 }
 
@@ -473,8 +473,8 @@ ProxyDatabase::OnSocketReady(gcc_unused unsigned flags) noexcept
 	if (idle == 0) {
 		try {
 			CheckError(connection);
-		} catch (const std::runtime_error &error) {
-			LogError(error);
+		} catch (...) {
+			LogError(std::current_exception());
 			Disconnect();
 			return false;
 		}
@@ -508,8 +508,8 @@ ProxyDatabase::OnIdle() noexcept
 	if (!mpd_send_idle_mask(connection, MPD_IDLE_DATABASE)) {
 		try {
 			ThrowError(connection);
-		} catch (const std::runtime_error &error) {
-			LogError(error);
+		} catch (...) {
+			LogError(std::current_exception());
 		}
 
 		SocketMonitor::Steal();
diff --git a/src/db/update/Archive.cxx b/src/db/update/Archive.cxx
index 6004ed835..e322c8ed3 100644
--- a/src/db/update/Archive.cxx
+++ b/src/db/update/Archive.cxx
@@ -34,7 +34,7 @@
 #include "Log.hxx"
 
 #include <string>
-#include <stdexcept>
+#include <exception>
 
 #include <string.h>
 
@@ -153,8 +153,8 @@ UpdateWalk::UpdateArchiveFile(Directory &parent, const char *name,
 	ArchiveFile *file;
 	try {
 		file = archive_file_open(&plugin, path_fs);
-	} catch (const std::runtime_error &e) {
-		LogError(e);
+	} catch (...) {
+		LogError(std::current_exception());
 		if (directory != nullptr)
 			editor.LockDeleteDirectory(directory);
 		return;
diff --git a/src/db/update/Container.cxx b/src/db/update/Container.cxx
index fc4ec416c..a12671758 100644
--- a/src/db/update/Container.cxx
+++ b/src/db/update/Container.cxx
@@ -119,9 +119,9 @@ UpdateWalk::UpdateContainerFile(Directory &directory,
 
 			modified = true;
 		}
-	} catch (const std::runtime_error &e) {
+	} catch (...) {
+		LogError(std::current_exception());
 		editor.LockDeleteDirectory(contdir);
-		LogError(e);
 		return false;
 	}
 
diff --git a/src/db/update/ExcludeList.cxx b/src/db/update/ExcludeList.cxx
index 82bf9be28..69c4cfab8 100644
--- a/src/db/update/ExcludeList.cxx
+++ b/src/db/update/ExcludeList.cxx
@@ -31,7 +31,7 @@
 #include "util/StringStrip.hxx"
 #include "Log.hxx"
 
-#include <stdexcept>
+#include <exception>
 
 #include <assert.h>
 #include <string.h>
@@ -62,8 +62,8 @@ try {
 	if (!IsFileNotFound(e))
 		LogError(e);
 	return false;
-} catch (const std::exception &e) {
-	LogError(e);
+} catch (...) {
+	LogError(std::current_exception());
 	return false;
 }
 
@@ -85,7 +85,7 @@ ExcludeList::Check(Path name_fs) const noexcept
 		try {
 			if (i.Check(NarrowPath(name_fs).c_str()))
 				return true;
-		} catch (const std::runtime_error &) {
+		} catch (...) {
 		}
 	}
 #else
diff --git a/src/db/update/InotifyUpdate.cxx b/src/db/update/InotifyUpdate.cxx
index 562315fa3..bd82f3e7a 100644
--- a/src/db/update/InotifyUpdate.cxx
+++ b/src/db/update/InotifyUpdate.cxx
@@ -187,8 +187,8 @@ recursive_watch_subdirectories(WatchDirectory *directory,
 		FileInfo fi;
 		try {
 			fi = FileInfo(child_path_fs);
-		} catch (const std::runtime_error &e) {
-			LogError(e);
+		} catch (...) {
+			LogError(std::current_exception());
 			continue;
 		}
 
@@ -198,8 +198,8 @@ recursive_watch_subdirectories(WatchDirectory *directory,
 		try {
 			ret = inotify_source->Add(child_path_fs.c_str(),
 						  IN_MASK);
-		} catch (const std::runtime_error &e) {
-			FormatError(e,
+		} catch (...) {
+			FormatError(std::current_exception(),
 				    "Failed to register %s",
 				    child_path_fs.c_str());
 			continue;
@@ -302,8 +302,8 @@ mpd_inotify_init(EventLoop &loop, Storage &storage, UpdateService &update,
 		inotify_source = new InotifySource(loop,
 						   mpd_inotify_callback,
 						   nullptr);
-	} catch (const std::runtime_error &e) {
-		LogError(e);
+	} catch (...) {
+		LogError(std::current_exception());
 		return;
 	}
 
@@ -312,8 +312,8 @@ mpd_inotify_init(EventLoop &loop, Storage &storage, UpdateService &update,
 	int descriptor;
 	try {
 		descriptor = inotify_source->Add(path.c_str(), IN_MASK);
-	} catch (const std::runtime_error &e) {
-		LogError(e);
+	} catch (...) {
+		LogError(std::current_exception());
 		delete inotify_source;
 		inotify_source = nullptr;
 		return;
diff --git a/src/db/update/UpdateIO.cxx b/src/db/update/UpdateIO.cxx
index 2623b0dc4..6977204de 100644
--- a/src/db/update/UpdateIO.cxx
+++ b/src/db/update/UpdateIO.cxx
@@ -36,8 +36,8 @@ GetInfo(Storage &storage, const char *uri_utf8, StorageFileInfo &info) noexcept
 try {
 	info = storage.GetInfo(uri_utf8, true);
 	return true;
-} catch (const std::runtime_error &e) {
-	LogError(e);
+} catch (...) {
+	LogError(std::current_exception());
 	return false;
 }
 
@@ -46,8 +46,8 @@ GetInfo(StorageDirectoryReader &reader, StorageFileInfo &info) noexcept
 try {
 	info = reader.GetInfo(true);
 	return true;
-} catch (const std::runtime_error &e) {
-	LogError(e);
+} catch (...) {
+	LogError(std::current_exception());
 	return false;
 }
 
@@ -58,7 +58,7 @@ DirectoryExists(Storage &storage, const Directory &directory) noexcept
 
 	try {
 		info = storage.GetInfo(directory.GetPath(), true);
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 		return false;
 	}
 
@@ -83,7 +83,7 @@ directory_child_is_regular(Storage &storage, const Directory &directory,
 try {
 	return GetDirectoryChildInfo(storage, directory, name_utf8)
 		.IsRegular();
-} catch (const std::runtime_error &) {
+} catch (...) {
 	return false;
 }
 
diff --git a/src/db/update/Walk.cxx b/src/db/update/Walk.cxx
index 8e58f126d..1bcf452d3 100644
--- a/src/db/update/Walk.cxx
+++ b/src/db/update/Walk.cxx
@@ -338,8 +338,8 @@ UpdateWalk::UpdateDirectory(Directory &directory,
 
 	try {
 		reader.reset(storage.OpenDirectory(directory.GetPath()));
-	} catch (const std::runtime_error &e) {
-		LogError(e);
+	} catch (...) {
+		LogError(std::current_exception());
 		return false;
 	}
 
diff --git a/src/decoder/Bridge.cxx b/src/decoder/Bridge.cxx
index e09e0e4dc..b4793c757 100644
--- a/src/decoder/Bridge.cxx
+++ b/src/decoder/Bridge.cxx
@@ -416,7 +416,7 @@ try {
 	assert(nbytes > 0 || is.IsEOF());
 
 	return nbytes;
-} catch (const std::runtime_error &e) {
+} catch (...) {
 	error = std::current_exception();
 	return 0;
 }
@@ -471,7 +471,7 @@ DecoderBridge::SubmitData(InputStream *is,
 			auto result = convert->Convert({data, length});
 			data = result.data;
 			length = result.size;
-		} catch (const std::runtime_error &e) {
+		} catch (...) {
 			/* the PCM conversion has failed - stop
 			   playback, since we have no better way to
 			   bail out */
diff --git a/src/decoder/DecoderAPI.cxx b/src/decoder/DecoderAPI.cxx
index 863f3d5aa..b7d7ae263 100644
--- a/src/decoder/DecoderAPI.cxx
+++ b/src/decoder/DecoderAPI.cxx
@@ -37,8 +37,8 @@ decoder_read(DecoderClient *client,
 
 	try {
 		return is.LockRead(buffer, length);
-	} catch (const std::runtime_error &e) {
-		LogError(e);
+	} catch (...) {
+		LogError(std::current_exception());
 		return 0;
 	}
 }
diff --git a/src/decoder/DecoderThread.cxx b/src/decoder/DecoderThread.cxx
index e9ce2769a..f09592828 100644
--- a/src/decoder/DecoderThread.cxx
+++ b/src/decoder/DecoderThread.cxx
@@ -112,7 +112,7 @@ decoder_stream_decode(const DecoderPlugin &plugin,
 	/* rewind the stream, so each plugin gets a fresh start */
 	try {
 		input_stream.Rewind();
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 	}
 
 	{
diff --git a/src/decoder/plugins/AudiofileDecoderPlugin.cxx b/src/decoder/plugins/AudiofileDecoderPlugin.cxx
index cf0d26bc6..b8b80b72c 100644
--- a/src/decoder/plugins/AudiofileDecoderPlugin.cxx
+++ b/src/decoder/plugins/AudiofileDecoderPlugin.cxx
@@ -30,7 +30,7 @@
 #include <audiofile.h>
 #include <af_vfs.h>
 
-#include <stdexcept>
+#include <exception>
 
 #include <assert.h>
 #include <stdio.h>
@@ -120,8 +120,8 @@ audiofile_file_seek(AFvirtualfile *vfile, AFfileoffset _offset,
 	try {
 		is.LockSeek(offset);
 		return is.GetOffset();
-	} catch (const std::runtime_error &e) {
-		LogError(e, "Seek failed");
+	} catch (...) {
+		LogError(std::current_exception(), "Seek failed");
 		return -1;
 	}
 }
diff --git a/src/decoder/plugins/DsdLib.cxx b/src/decoder/plugins/DsdLib.cxx
index c1c026e87..0961d7249 100644
--- a/src/decoder/plugins/DsdLib.cxx
+++ b/src/decoder/plugins/DsdLib.cxx
@@ -57,7 +57,7 @@ dsdlib_skip_to(DecoderClient *client, InputStream &is,
 	if (is.IsSeekable()) {
 		try {
 			is.LockSeek(offset);
-		} catch (const std::runtime_error &) {
+		} catch (...) {
 			return false;
 		}
 	}
@@ -81,7 +81,7 @@ dsdlib_skip(DecoderClient *client, InputStream &is,
 	if (is.IsSeekable()) {
 		try {
 			is.LockSeek(is.GetOffset() + delta);
-		} catch (const std::runtime_error &) {
+		} catch (...) {
 			return false;
 		}
 	}
diff --git a/src/decoder/plugins/FaadDecoderPlugin.cxx b/src/decoder/plugins/FaadDecoderPlugin.cxx
index ef1bd4fa3..3030886c0 100644
--- a/src/decoder/plugins/FaadDecoderPlugin.cxx
+++ b/src/decoder/plugins/FaadDecoderPlugin.cxx
@@ -31,7 +31,7 @@
 
 #include <neaacdec.h>
 
-#include <stdexcept>
+#include <exception>
 
 #include <assert.h>
 #include <string.h>
@@ -196,7 +196,7 @@ faad_song_duration(DecoderBuffer &buffer, InputStream &is)
 
 		try {
 			is.LockSeek(tagsize);
-		} catch (const std::runtime_error &) {
+		} catch (...) {
 		}
 
 		buffer.Clear();
@@ -316,7 +316,7 @@ faad_get_file_time(InputStream &is)
 		try {
 			faad_decoder_init(decoder, buffer, audio_format);
 			recognized = true;
-		} catch (const std::runtime_error &e) {
+		} catch (...) {
 		}
 	}
 
diff --git a/src/decoder/plugins/FfmpegDecoderPlugin.cxx b/src/decoder/plugins/FfmpegDecoderPlugin.cxx
index 4e7ac0fd6..9c4b929e2 100644
--- a/src/decoder/plugins/FfmpegDecoderPlugin.cxx
+++ b/src/decoder/plugins/FfmpegDecoderPlugin.cxx
@@ -483,7 +483,7 @@ ffmpeg_probe(DecoderClient *client, InputStream &is)
 
 	try {
 		is.LockRewind();
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 		return nullptr;
 	}
 
@@ -814,8 +814,8 @@ ffmpeg_decode(DecoderClient &client, InputStream &input)
 	try {
 		format_context =FfmpegOpenInput(stream.io, input.GetURI(),
 						input_format);
-	} catch (const std::runtime_error &e) {
-		LogError(e);
+	} catch (...) {
+		LogError(std::current_exception());
 		return;
 	}
 
@@ -869,7 +869,7 @@ ffmpeg_scan_stream(InputStream &is,
 	AVFormatContext *f;
 	try {
 		f = FfmpegOpenInput(stream.io, is.GetURI(), input_format);
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 		return false;
 	}
 
diff --git a/src/decoder/plugins/FfmpegIo.cxx b/src/decoder/plugins/FfmpegIo.cxx
index 755a8fcfe..780645fbe 100644
--- a/src/decoder/plugins/FfmpegIo.cxx
+++ b/src/decoder/plugins/FfmpegIo.cxx
@@ -25,7 +25,7 @@
 #include "../DecoderAPI.hxx"
 #include "input/InputStream.hxx"
 
-#include <stdexcept>
+#include <exception>
 
 AvioStream::~AvioStream()
 {
@@ -72,7 +72,7 @@ AvioStream::Seek(int64_t pos, int whence)
 	try {
 		input.LockSeek(pos);
 		return input.GetOffset();
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 		return -1;
 	}
 }
diff --git a/src/decoder/plugins/FlacCommon.cxx b/src/decoder/plugins/FlacCommon.cxx
index 1abd5682e..504096bd3 100644
--- a/src/decoder/plugins/FlacCommon.cxx
+++ b/src/decoder/plugins/FlacCommon.cxx
@@ -27,7 +27,7 @@
 #include "util/ConstBuffer.hxx"
 #include "Log.hxx"
 
-#include <stdexcept>
+#include <exception>
 
 bool
 FlacDecoder::Initialize(unsigned sample_rate, unsigned bits_per_sample,
@@ -39,8 +39,8 @@ FlacDecoder::Initialize(unsigned sample_rate, unsigned bits_per_sample,
 	try {
 		pcm_import.Open(sample_rate, bits_per_sample,
 				channels);
-	} catch (const std::runtime_error &e) {
-		LogError(e);
+	} catch (...) {
+		LogError(std::current_exception());
 		unsupported = true;
 		return false;
 	}
diff --git a/src/decoder/plugins/FlacDecoderPlugin.cxx b/src/decoder/plugins/FlacDecoderPlugin.cxx
index 688382d4a..d34b7f9a8 100644
--- a/src/decoder/plugins/FlacDecoderPlugin.cxx
+++ b/src/decoder/plugins/FlacDecoderPlugin.cxx
@@ -330,7 +330,7 @@ oggflac_decode(DecoderClient &client, InputStream &input_stream)
 	   moved it */
 	try {
 		input_stream.LockRewind();
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 	}
 
 	flac_decode_internal(client, input_stream, true);
diff --git a/src/decoder/plugins/FlacIOHandle.cxx b/src/decoder/plugins/FlacIOHandle.cxx
index bdd433491..21befb89a 100644
--- a/src/decoder/plugins/FlacIOHandle.cxx
+++ b/src/decoder/plugins/FlacIOHandle.cxx
@@ -55,7 +55,7 @@ FlacIORead(void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle)
 				: EINVAL;
 			return 0;
 #endif
-		} catch (const std::runtime_error &) {
+		} catch (...) {
 			/* just some random non-zero errno value */
 			errno = EINVAL;
 			return 0;
@@ -96,8 +96,8 @@ FlacIOSeek(FLAC__IOHandle handle, FLAC__int64 _offset, int whence)
 	try {
 		is->LockSeek(offset);
 		return 0;
-	} catch (const std::runtime_error &e) {
-		LogError(e);
+	} catch (...) {
+		LogError(std::current_exception());
 		return -1;
 	}
 }
diff --git a/src/decoder/plugins/FlacInput.cxx b/src/decoder/plugins/FlacInput.cxx
index 116eb4340..773c83cc9 100644
--- a/src/decoder/plugins/FlacInput.cxx
+++ b/src/decoder/plugins/FlacInput.cxx
@@ -25,7 +25,7 @@
 #include "Log.hxx"
 #include "Compiler.h"
 
-#include <stdexcept>
+#include <exception>
 
 FLAC__StreamDecoderReadStatus
 FlacInput::Read(FLAC__byte buffer[], size_t *bytes)
@@ -54,8 +54,8 @@ FlacInput::Seek(FLAC__uint64 absolute_byte_offset)
 	try {
 		input_stream.LockSeek(absolute_byte_offset);
 		return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
-	} catch (const std::runtime_error &e) {
-		LogError(e);
+	} catch (...) {
+		LogError(std::current_exception());
 		return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
 	}
 }
diff --git a/src/decoder/plugins/MadDecoderPlugin.cxx b/src/decoder/plugins/MadDecoderPlugin.cxx
index f0b707a02..b5e14c38c 100644
--- a/src/decoder/plugins/MadDecoderPlugin.cxx
+++ b/src/decoder/plugins/MadDecoderPlugin.cxx
@@ -212,7 +212,7 @@ MadDecoder::Seek(long offset)
 {
 	try {
 		input_stream.LockSeek(offset);
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 		return false;
 	}
 
diff --git a/src/decoder/plugins/MpcdecDecoderPlugin.cxx b/src/decoder/plugins/MpcdecDecoderPlugin.cxx
index 0e62fd5d8..bc52b20ee 100644
--- a/src/decoder/plugins/MpcdecDecoderPlugin.cxx
+++ b/src/decoder/plugins/MpcdecDecoderPlugin.cxx
@@ -32,7 +32,7 @@
 
 #include <mpc/mpcdec.h>
 
-#include <stdexcept>
+#include <exception>
 
 #include <math.h>
 
@@ -67,7 +67,7 @@ mpc_seek_cb(mpc_reader *reader, mpc_int32_t offset)
 	try {
 		data->is.LockSeek(offset);
 		return true;
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 		return false;
 	}
 }
diff --git a/src/decoder/plugins/OggDecoder.cxx b/src/decoder/plugins/OggDecoder.cxx
index ddc5500fd..84c71b6a8 100644
--- a/src/decoder/plugins/OggDecoder.cxx
+++ b/src/decoder/plugins/OggDecoder.cxx
@@ -22,7 +22,7 @@
 #include "lib/xiph/OggFind.hxx"
 #include "input/InputStream.hxx"
 
-#include <stdexcept>
+#include <exception>
 
 /**
  * Load the end-of-stream packet and restore the previous file
@@ -55,7 +55,7 @@ OggDecoder::LoadEndPacket(ogg_packet &packet) const
 	/* restore the previous file position */
 	try {
 		input_stream.LockSeek(old_offset);
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 	}
 
 	return result;
diff --git a/src/decoder/plugins/OpusDecoderPlugin.cxx b/src/decoder/plugins/OpusDecoderPlugin.cxx
index 4d0129e27..fa0fc4303 100644
--- a/src/decoder/plugins/OpusDecoderPlugin.cxx
+++ b/src/decoder/plugins/OpusDecoderPlugin.cxx
@@ -261,7 +261,7 @@ MPDOpusDecoder::Seek(uint64_t where_frame)
 	try {
 		SeekGranulePos(where_granulepos);
 		return true;
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 		return false;
 	}
 }
@@ -277,7 +277,7 @@ mpd_opus_stream_decode(DecoderClient &client,
 	   moved it */
 	try {
 		input_stream.LockRewind();
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 	}
 
 	DecoderReader reader(client, input_stream);
diff --git a/src/decoder/plugins/PcmDecoderPlugin.cxx b/src/decoder/plugins/PcmDecoderPlugin.cxx
index 7e49914d3..de8026108 100644
--- a/src/decoder/plugins/PcmDecoderPlugin.cxx
+++ b/src/decoder/plugins/PcmDecoderPlugin.cxx
@@ -31,7 +31,7 @@
 #include "util/MimeType.hxx"
 #include "Log.hxx"
 
-#include <stdexcept>
+#include <exception>
 
 #include <assert.h>
 #include <string.h>
@@ -105,8 +105,8 @@ pcm_stream_decode(DecoderClient &client, InputStream &is)
 
 			try {
 				CheckSampleRate(value);
-			} catch (const std::runtime_error &e) {
-				LogError(e);
+			} catch (...) {
+				LogError(std::current_exception());
 				return;
 			}
 
@@ -127,8 +127,8 @@ pcm_stream_decode(DecoderClient &client, InputStream &is)
 
 			try {
 				CheckChannelCount(value);
-			} catch (const std::runtime_error &e) {
-				LogError(e);
+			} catch (...) {
+				LogError(std::current_exception());
 				return;
 			}
 
@@ -196,8 +196,8 @@ pcm_stream_decode(DecoderClient &client, InputStream &is)
 				is.LockSeek(offset);
 				buffer.Clear();
 				client.CommandFinished();
-			} catch (const std::runtime_error &e) {
-				LogError(e);
+			} catch (...) {
+				LogError(std::current_exception());
 				client.SeekError();
 			}
 
diff --git a/src/decoder/plugins/SndfileDecoderPlugin.cxx b/src/decoder/plugins/SndfileDecoderPlugin.cxx
index 2f49c7f28..3dfdf62ed 100644
--- a/src/decoder/plugins/SndfileDecoderPlugin.cxx
+++ b/src/decoder/plugins/SndfileDecoderPlugin.cxx
@@ -26,7 +26,7 @@
 #include "util/Domain.hxx"
 #include "Log.hxx"
 
-#include <stdexcept>
+#include <exception>
 
 #include <sndfile.h>
 
@@ -93,8 +93,8 @@ sndfile_vio_seek(sf_count_t _offset, int whence, void *user_data)
 	try {
 		is.LockSeek(offset);
 		return is.GetOffset();
-	} catch (const std::runtime_error &e) {
-		LogError(e, "Seek failed");
+	} catch (...) {
+		LogError(std::current_exception(), "Seek failed");
 		return -1;
 	}
 }
diff --git a/src/decoder/plugins/VorbisDecoderPlugin.cxx b/src/decoder/plugins/VorbisDecoderPlugin.cxx
index fbbc0264a..c99427fd9 100644
--- a/src/decoder/plugins/VorbisDecoderPlugin.cxx
+++ b/src/decoder/plugins/VorbisDecoderPlugin.cxx
@@ -129,7 +129,7 @@ VorbisDecoder::Seek(uint64_t where_frame)
 		SeekGranulePos(where_granulepos);
 		vorbis_synthesis_restart(&dsp);
 		return true;
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 		return false;
 	}
 }
@@ -323,7 +323,7 @@ vorbis_stream_decode(DecoderClient &client,
 	   moved it */
 	try {
 		input_stream.LockRewind();
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 	}
 
 	DecoderReader reader(client, input_stream);
diff --git a/src/decoder/plugins/WavpackDecoderPlugin.cxx b/src/decoder/plugins/WavpackDecoderPlugin.cxx
index 63615ec3d..51ec3861c 100644
--- a/src/decoder/plugins/WavpackDecoderPlugin.cxx
+++ b/src/decoder/plugins/WavpackDecoderPlugin.cxx
@@ -295,7 +295,7 @@ struct WavpackInput {
 		try {
 			is.LockSeek(pos);
 			return 0;
-		} catch (const std::runtime_error &) {
+		} catch (...) {
 			return -1;
 		}
 	}
@@ -520,7 +520,7 @@ wavpack_open_wvc(DecoderClient &client, const char *uri)
 
 	try {
 		return client.OpenUri(uri);
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 		return nullptr;
 	}
 }
diff --git a/src/event/ServerSocket.cxx b/src/event/ServerSocket.cxx
index ef069b00e..b9a1c82bc 100644
--- a/src/event/ServerSocket.cxx
+++ b/src/event/ServerSocket.cxx
@@ -220,11 +220,11 @@ ServerSocket::Open()
 
 		try {
 			i.Open();
-		} catch (const std::runtime_error &e) {
+		} catch (...) {
 			if (good != nullptr && good->GetSerial() == i.GetSerial()) {
 				const auto address_string = i.ToString();
 				const auto good_string = good->ToString();
-				FormatError(e,
+				FormatError(std::current_exception(),
 					    "bind to '%s' failed "
 					    "(continuing anyway, because "
 					    "binding to '%s' succeeded)",
diff --git a/src/filter/plugins/ReplayGainFilterPlugin.cxx b/src/filter/plugins/ReplayGainFilterPlugin.cxx
index abe869a09..1a77d44dc 100644
--- a/src/filter/plugins/ReplayGainFilterPlugin.cxx
+++ b/src/filter/plugins/ReplayGainFilterPlugin.cxx
@@ -29,7 +29,7 @@
 #include "util/Domain.hxx"
 #include "Log.hxx"
 
-#include <stdexcept>
+#include <exception>
 
 #include <assert.h>
 
@@ -163,8 +163,9 @@ ReplayGainFilter::Update()
 
 		try {
 			mixer_set_volume(mixer, _volume);
-		} catch (const std::runtime_error &e) {
-			LogError(e, "Failed to update hardware mixer");
+		} catch (...) {
+			LogError(std::current_exception(),
+				 "Failed to update hardware mixer");
 		}
 	} else
 		pv.SetVolume(volume);
diff --git a/src/fs/AllocatedPath.cxx b/src/fs/AllocatedPath.cxx
index 0bf2ba4ad..ffa307905 100644
--- a/src/fs/AllocatedPath.cxx
+++ b/src/fs/AllocatedPath.cxx
@@ -23,7 +23,7 @@
 #include "Charset.hxx"
 #include "Compiler.h"
 
-#include <stdexcept>
+#include <exception>
 
 /* no inlining, please */
 AllocatedPath::~AllocatedPath() {}
@@ -34,7 +34,7 @@ AllocatedPath::FromUTF8(const char *path_utf8) noexcept
 #if defined(HAVE_FS_CHARSET) || defined(_WIN32)
 	try {
 		return AllocatedPath(::PathFromUTF8(path_utf8));
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 		return nullptr;
 	}
 #else
@@ -63,7 +63,7 @@ AllocatedPath::ToUTF8() const noexcept
 {
 	try {
 		return ::PathToUTF8(c_str());
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 		return std::string();
 	}
 }
diff --git a/src/fs/CheckFile.cxx b/src/fs/CheckFile.cxx
index fa4ac0ead..633ccc437 100644
--- a/src/fs/CheckFile.cxx
+++ b/src/fs/CheckFile.cxx
@@ -62,6 +62,6 @@ try {
 				    "No permission to read directory: %s",
 				    path_fs.ToUTF8().c_str());
 	}
-} catch (const std::runtime_error &e) {
-	LogError(e);
+} catch (...) {
+	LogError(std::current_exception());
 }
diff --git a/src/fs/Path.cxx b/src/fs/Path.cxx
index b8745915f..640c74dbe 100644
--- a/src/fs/Path.cxx
+++ b/src/fs/Path.cxx
@@ -21,14 +21,12 @@
 #include "Path.hxx"
 #include "Charset.hxx"
 
-#include <stdexcept>
-
 std::string
 Path::ToUTF8() const noexcept
 {
 	try {
 		return ::PathToUTF8(c_str());
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 		return std::string();
 	}
 }
diff --git a/src/input/Init.cxx b/src/input/Init.cxx
index 7272339d0..6a40f5491 100644
--- a/src/input/Init.cxx
+++ b/src/input/Init.cxx
@@ -62,7 +62,7 @@ input_stream_global_init(EventLoop &event_loop)
 				    "Input plugin '%s' is unavailable",
 				    plugin->name);
 			continue;
-		} catch (const std::runtime_error &e) {
+		} catch (...) {
 			std::throw_with_nested(FormatRuntimeError("Failed to initialize input plugin '%s'",
 								  plugin->name));
 		}
diff --git a/src/input/TextInputStream.cxx b/src/input/TextInputStream.cxx
index d8fd420b9..123912f8a 100644
--- a/src/input/TextInputStream.cxx
+++ b/src/input/TextInputStream.cxx
@@ -63,8 +63,8 @@ TextInputStream::ReadLine()
 
 		try {
 			nbytes = is->LockRead(dest.data, dest.size);
-		} catch (const std::runtime_error &e) {
-			LogError(e);
+		} catch (...) {
+			LogError(std::current_exception());
 			return nullptr;
 		}
 
diff --git a/src/lib/icu/CaseFold.cxx b/src/lib/icu/CaseFold.cxx
index d0f086897..005bff6a1 100644
--- a/src/lib/icu/CaseFold.cxx
+++ b/src/lib/icu/CaseFold.cxx
@@ -42,7 +42,6 @@
 #endif
 
 #include <memory>
-#include <stdexcept>
 
 #include <assert.h>
 #include <string.h>
@@ -95,7 +94,7 @@ try {
 #else
 #error not implemented
 #endif
-} catch (const std::runtime_error &) {
+} catch (...) {
 	return AllocatedString<>::Duplicate(src);
 }
 
diff --git a/src/lib/icu/Collate.cxx b/src/lib/icu/Collate.cxx
index 7772785aa..aaff50acf 100644
--- a/src/lib/icu/Collate.cxx
+++ b/src/lib/icu/Collate.cxx
@@ -97,7 +97,7 @@ IcuCollate(const char *a, const char *b) noexcept
 
 		return ucol_strcoll(collator, au.begin(), au.size(),
 				    bu.begin(), bu.size());
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 		/* fall back to plain strcasecmp() */
 		return strcasecmp(a, b);
 	}
@@ -108,18 +108,18 @@ IcuCollate(const char *a, const char *b) noexcept
 
 	try {
 		wa = MultiByteToWideChar(CP_UTF8, a);
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 		try {
 			wb = MultiByteToWideChar(CP_UTF8, b);
 			return -1;
-		} catch (const std::runtime_error &) {
+		} catch (...) {
 			return 0;
 		}
 	}
 
 	try {
 		wb = MultiByteToWideChar(CP_UTF8, b);
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 		return 1;
 	}
 
diff --git a/src/lib/xiph/OggFind.cxx b/src/lib/xiph/OggFind.cxx
index 90b0dd41b..d989bcea2 100644
--- a/src/lib/xiph/OggFind.cxx
+++ b/src/lib/xiph/OggFind.cxx
@@ -22,8 +22,6 @@
 #include "lib/xiph/OggSyncState.hxx"
 #include "input/InputStream.hxx"
 
-#include <stdexcept>
-
 bool
 OggFindEOS(OggSyncState &oy, ogg_stream_state &os, ogg_packet &packet)
 {
@@ -51,7 +49,7 @@ OggSeekPageAtOffset(OggSyncState &oy, ogg_stream_state &os, InputStream &is,
 
 	try {
 		is.LockSeek(offset);
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 		return false;
 	}
 
diff --git a/src/mixer/MixerAll.cxx b/src/mixer/MixerAll.cxx
index 822ffc736..7841687ad 100644
--- a/src/mixer/MixerAll.cxx
+++ b/src/mixer/MixerAll.cxx
@@ -43,8 +43,8 @@ output_mixer_get_volume(const AudioOutputControl &ao) noexcept
 
 	try {
 		return mixer_get_volume(mixer);
-	} catch (const std::runtime_error &e) {
-		FormatError(e,
+	} catch (...) {
+		FormatError(std::current_exception(),
 			    "Failed to read mixer for '%s'",
 			    ao.GetName());
 		return -1;
@@ -86,8 +86,8 @@ output_mixer_set_volume(AudioOutputControl &ao, unsigned volume) noexcept
 	try {
 		mixer_set_volume(mixer, volume);
 		return true;
-	} catch (const std::runtime_error &e) {
-		FormatError(e,
+	} catch (...) {
+		FormatError(std::current_exception(),
 			    "Failed to set mixer for '%s'",
 			    ao.GetName());
 		return false;
diff --git a/src/mixer/plugins/AlsaMixerPlugin.cxx b/src/mixer/plugins/AlsaMixerPlugin.cxx
index 04c3c53ca..924da908d 100644
--- a/src/mixer/plugins/AlsaMixerPlugin.cxx
+++ b/src/mixer/plugins/AlsaMixerPlugin.cxx
@@ -149,7 +149,7 @@ alsa_mixer_elem_callback(snd_mixer_elem_t *elem, unsigned mask)
 		try {
 			int volume = mixer.GetVolume();
 			mixer.listener.OnMixerVolumeChanged(mixer, volume);
-		} catch (const std::runtime_error &) {
+		} catch (...) {
 		}
 	}
 
diff --git a/src/neighbor/plugins/UpnpNeighborPlugin.cxx b/src/neighbor/plugins/UpnpNeighborPlugin.cxx
index fba10328f..6d160be7f 100644
--- a/src/neighbor/plugins/UpnpNeighborPlugin.cxx
+++ b/src/neighbor/plugins/UpnpNeighborPlugin.cxx
@@ -104,8 +104,8 @@ UpnpNeighborExplorer::GetList() const noexcept
 
 	try {
 		tmp = discovery->GetDirectories();
-	} catch (const std::runtime_error &e) {
-		LogError(e);
+	} catch (...) {
+		LogError(std::current_exception());
 	}
 
 	List result;
diff --git a/src/output/Control.cxx b/src/output/Control.cxx
index 211044e57..468a48ec7 100644
--- a/src/output/Control.cxx
+++ b/src/output/Control.cxx
@@ -205,8 +205,9 @@ AudioOutputControl::Open(const AudioFormat audio_format,
 	if (open2 && output->mixer != nullptr) {
 		try {
 			mixer_open(output->mixer);
-		} catch (const std::runtime_error &e) {
-			FormatError(e, "Failed to open mixer for '%s'",
+		} catch (...) {
+			FormatError(std::current_exception(),
+				    "Failed to open mixer for '%s'",
 				    GetName());
 		}
 	}
diff --git a/src/output/Filtered.cxx b/src/output/Filtered.cxx
index 45d2d92be..2b434feab 100644
--- a/src/output/Filtered.cxx
+++ b/src/output/Filtered.cxx
@@ -45,7 +45,7 @@ FilteredAudioOutput::Enable()
 {
 	try {
 		output->Enable();
-	} catch (const std::runtime_error &e) {
+	} catch (...) {
 		std::throw_with_nested(FormatRuntimeError("Failed to enable output %s",
 							  GetLogName()));
 	}
@@ -62,7 +62,7 @@ FilteredAudioOutput::ConfigureConvertFilter()
 {
 	try {
 		convert_filter_set(convert_filter.Get(), out_audio_format);
-	} catch (const std::runtime_error &e) {
+	} catch (...) {
 		std::throw_with_nested(FormatRuntimeError("Failed to convert for %s",
 							  GetLogName()));
 	}
@@ -75,7 +75,7 @@ FilteredAudioOutput::OpenOutputAndConvert(AudioFormat desired_audio_format)
 
 	try {
 		output->Open(out_audio_format);
-	} catch (const std::runtime_error &e) {
+	} catch (...) {
 		std::throw_with_nested(FormatRuntimeError("Failed to open %s",
 							  GetLogName()));
 	}
@@ -87,7 +87,7 @@ FilteredAudioOutput::OpenOutputAndConvert(AudioFormat desired_audio_format)
 
 	try {
 		ConfigureConvertFilter();
-	} catch (const std::runtime_error &e) {
+	} catch (...) {
 		output->Close();
 
 		if (out_audio_format.format == SampleFormat::DSD) {
@@ -97,7 +97,7 @@ FilteredAudioOutput::OpenOutputAndConvert(AudioFormat desired_audio_format)
 			   implemented; our last resort is to give up
 			   DSD and fall back to PCM */
 
-			LogError(e);
+			LogError(std::current_exception());
 			FormatError(output_domain, "Retrying without DSD");
 
 			desired_audio_format.format = SampleFormat::FLOAT;
@@ -184,8 +184,8 @@ FilteredAudioOutput::IteratePause() noexcept
 {
 	try {
 		return output->Pause();
-	} catch (const std::runtime_error &e) {
-		FormatError(e, "Failed to pause %s",
+	} catch (...) {
+		FormatError(std::current_exception(), "Failed to pause %s",
 			    GetLogName());
 		return false;
 	}
diff --git a/src/output/Init.cxx b/src/output/Init.cxx
index 06d801926..70bb960a3 100644
--- a/src/output/Init.cxx
+++ b/src/output/Init.cxx
@@ -186,11 +186,11 @@ FilteredAudioOutput::Configure(const ConfigBlock &block)
 	try {
 		filter_chain_parse(*prepared_filter,
 				   block.GetBlockValue(AUDIO_FILTERS, ""));
-	} catch (const std::runtime_error &e) {
+	} catch (...) {
 		/* It's not really fatal - Part of the filter chain
 		   has been set up already and even an empty one will
 		   work (if only with unexpected behaviour) */
-		FormatError(e,
+		FormatError(std::current_exception(),
 			    "Failed to initialize filter chain for '%s'",
 			    name);
 	}
@@ -232,8 +232,8 @@ FilteredAudioOutput::Setup(EventLoop &event_loop,
 						mixer_plugin,
 						*prepared_filter,
 						mixer_listener);
-	} catch (const std::runtime_error &e) {
-		FormatError(e,
+	} catch (...) {
+		FormatError(std::current_exception(),
 			    "Failed to initialize hardware mixer for '%s'",
 			    name);
 	}
diff --git a/src/output/MultipleOutputs.cxx b/src/output/MultipleOutputs.cxx
index 4d6af2543..c2f26ac7d 100644
--- a/src/output/MultipleOutputs.cxx
+++ b/src/output/MultipleOutputs.cxx
@@ -57,7 +57,7 @@ LoadOutput(EventLoop &event_loop,
 try {
 	return audio_output_new(event_loop, replay_gain_config, block,
 				mixer_listener);
-} catch (const std::runtime_error &e) {
+} catch (...) {
 	if (block.line > 0)
 		std::throw_with_nested(FormatRuntimeError("Failed to configure output in line %i",
 							  block.line));
diff --git a/src/output/Thread.cxx b/src/output/Thread.cxx
index b184c5edc..f06a7430a 100644
--- a/src/output/Thread.cxx
+++ b/src/output/Thread.cxx
@@ -72,7 +72,7 @@ AudioOutputControl::InternalOpen2(const AudioFormat in_audio_format)
 
 		try {
 			output->ConfigureConvertFilter();
-		} catch (const std::runtime_error &e) {
+		} catch (...) {
 			open = false;
 
 			{
@@ -107,8 +107,8 @@ AudioOutputControl::InternalEnable() noexcept
 
 		really_enabled = true;
 		return true;
-	} catch (const std::runtime_error &e) {
-		LogError(e);
+	} catch (...) {
+		LogError(std::current_exception());
 		fail_timer.Update();
 		last_error = std::current_exception();
 		return false;
@@ -149,7 +149,7 @@ AudioOutputControl::InternalOpen(const AudioFormat in_audio_format,
 					output->prepared_replay_gain_filter,
 					output->prepared_other_replay_gain_filter,
 					output->prepared_filter);
-		} catch (const std::runtime_error &e) {
+		} catch (...) {
 			std::throw_with_nested(FormatRuntimeError("Failed to open filter for %s",
 								  GetLogName()));
 		}
@@ -160,8 +160,8 @@ AudioOutputControl::InternalOpen(const AudioFormat in_audio_format,
 			source.Close();
 			throw;
 		}
-	} catch (const std::runtime_error &e) {
-		LogError(e);
+	} catch (...) {
+		LogError(std::current_exception());
 		fail_timer.Update();
 		last_error = std::current_exception();
 	}
@@ -231,8 +231,9 @@ bool
 AudioOutputControl::FillSourceOrClose()
 try {
 	return source.Fill(mutex);
-} catch (const std::runtime_error &e) {
-	FormatError(e, "Failed to filter for %s", GetLogName());
+} catch (...) {
+	FormatError(std::current_exception(),
+		    "Failed to filter for %s", GetLogName());
 
 	InternalClose(false);
 
@@ -251,8 +252,9 @@ AudioOutputControl::PlayChunk() noexcept
 		const ScopeUnlock unlock(mutex);
 		try {
 			output->SendTag(*tag);
-		} catch (const std::runtime_error &e) {
-			FormatError(e, "Failed to send tag to %s",
+		} catch (...) {
+			FormatError(std::current_exception(),
+				    "Failed to send tag to %s",
 				    GetLogName());
 		}
 	}
@@ -273,8 +275,9 @@ AudioOutputControl::PlayChunk() noexcept
 			const ScopeUnlock unlock(mutex);
 			nbytes = output->Play(data.data, data.size);
 			assert(nbytes <= data.size);
-		} catch (const std::runtime_error &e) {
-			FormatError(e, "Failed to play on %s", GetLogName());
+		} catch (...) {
+			FormatError(std::current_exception(),
+				    "Failed to play on %s", GetLogName());
 			nbytes = 0;
 		}
 
@@ -382,8 +385,8 @@ AudioOutputControl::Task()
 
 	try {
 		SetThreadRealtime();
-	} catch (const std::runtime_error &e) {
-		LogError(e,
+	} catch (...) {
+		LogError(std::current_exception(),
 			 "OutputThread could not get realtime scheduling, continuing anyway");
 	}
 
diff --git a/src/output/plugins/AlsaOutputPlugin.cxx b/src/output/plugins/AlsaOutputPlugin.cxx
index 8a7acee95..de3e11933 100644
--- a/src/output/plugins/AlsaOutputPlugin.cxx
+++ b/src/output/plugins/AlsaOutputPlugin.cxx
@@ -875,7 +875,7 @@ try {
 		   call */
 		return;
 	}
-} catch (const std::runtime_error &) {
+} catch (...) {
 	MultiSocketMonitor::Reset();
 	LockCaughtError();
 }
diff --git a/src/output/plugins/FifoOutputPlugin.cxx b/src/output/plugins/FifoOutputPlugin.cxx
index 6c0e1b739..cc76af1a9 100644
--- a/src/output/plugins/FifoOutputPlugin.cxx
+++ b/src/output/plugins/FifoOutputPlugin.cxx
@@ -92,8 +92,8 @@ FifoOutput::Delete()
 
 	try {
 		RemoveFile(path);
-	} catch (const std::runtime_error &e) {
-		LogError(e, "Could not remove FIFO");
+	} catch (...) {
+		LogError(std::current_exception(), "Could not remove FIFO");
 		return;
 	}
 
diff --git a/src/output/plugins/PulseOutputPlugin.cxx b/src/output/plugins/PulseOutputPlugin.cxx
index 11fd960e9..7c5f9a551 100644
--- a/src/output/plugins/PulseOutputPlugin.cxx
+++ b/src/output/plugins/PulseOutputPlugin.cxx
@@ -856,7 +856,7 @@ try {
 	PulseOutput po(empty);
 	po.WaitConnection();
 	return true;
-} catch (const std::runtime_error &e) {
+} catch (...) {
 	return false;
 }
 
diff --git a/src/output/plugins/RecorderOutputPlugin.cxx b/src/output/plugins/RecorderOutputPlugin.cxx
index 4d39df9e2..e7c3842b6 100644
--- a/src/output/plugins/RecorderOutputPlugin.cxx
+++ b/src/output/plugins/RecorderOutputPlugin.cxx
@@ -154,7 +154,7 @@ RecorderOutput::Open(AudioFormat &audio_format)
 
 	try {
 		encoder = prepared_encoder->Open(audio_format);
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 		delete file;
 		throw;
 	}
@@ -162,7 +162,7 @@ RecorderOutput::Open(AudioFormat &audio_format)
 	if (!HasDynamicPath()) {
 		try {
 			EncoderToFile();
-		} catch (const std::runtime_error &) {
+		} catch (...) {
 			delete encoder;
 			throw;
 		}
@@ -218,8 +218,8 @@ RecorderOutput::Close() noexcept
 
 	try {
 		Commit();
-	} catch (const std::exception &e) {
-		LogError(e);
+	} catch (...) {
+		LogError(std::current_exception());
 	}
 
 	if (HasDynamicPath()) {
@@ -238,8 +238,8 @@ RecorderOutput::FinishFormat()
 
 	try {
 		Commit();
-	} catch (const std::exception &e) {
-		LogError(e);
+	} catch (...) {
+		LogError(std::current_exception());
 	}
 
 	file = nullptr;
@@ -270,7 +270,7 @@ RecorderOutput::ReopenFormat(AllocatedPath &&new_path)
 
 	try {
 		EncoderToOutputStream(*new_file, *encoder);
-	} catch (const std::exception &e) {
+	} catch (...) {
 		delete encoder;
 		delete new_file;
 		throw;
@@ -302,8 +302,8 @@ RecorderOutput::SendTag(const Tag &tag)
 
 		try {
 			new_path = ParsePath(p);
-		} catch (const std::runtime_error &e) {
-			LogError(e);
+		} catch (...) {
+			LogError(std::current_exception());
 			FinishFormat();
 			return;
 		}
@@ -313,8 +313,8 @@ RecorderOutput::SendTag(const Tag &tag)
 
 			try {
 				ReopenFormat(std::move(new_path));
-			} catch (const std::runtime_error &e) {
-				LogError(e);
+			} catch (...) {
+				LogError(std::current_exception());
 				return;
 			}
 		}
diff --git a/src/output/plugins/ShoutOutputPlugin.cxx b/src/output/plugins/ShoutOutputPlugin.cxx
index 97df09b21..9332fdaa9 100644
--- a/src/output/plugins/ShoutOutputPlugin.cxx
+++ b/src/output/plugins/ShoutOutputPlugin.cxx
@@ -251,7 +251,7 @@ ShoutOutput::Close() noexcept
 	try {
 		encoder->End();
 		WritePage();
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 		/* ignore */
 	}
 
diff --git a/src/output/plugins/httpd/HttpdOutputPlugin.cxx b/src/output/plugins/httpd/HttpdOutputPlugin.cxx
index 89c306560..e7689b55d 100644
--- a/src/output/plugins/httpd/HttpdOutputPlugin.cxx
+++ b/src/output/plugins/httpd/HttpdOutputPlugin.cxx
@@ -179,7 +179,7 @@ HttpdOutput::ReadPage()
 		   buffer underruns */
 		try {
 			encoder->Flush();
-		} catch (const std::runtime_error &) {
+		} catch (...) {
 			/* ignore */
 		}
 
@@ -376,7 +376,7 @@ HttpdOutput::SendTag(const Tag &tag)
 
 		try {
 			encoder->PreTag();
-		} catch (const std::runtime_error &) {
+		} catch (...) {
 			/* ignore */
 		}
 
@@ -388,7 +388,7 @@ HttpdOutput::SendTag(const Tag &tag)
 		try {
 			encoder->SendTag(tag);
 			encoder->Flush();
-		} catch (const std::runtime_error &) {
+		} catch (...) {
 			/* ignore */
 		}
 
diff --git a/src/player/Thread.cxx b/src/player/Thread.cxx
index 23409d308..662901a43 100644
--- a/src/player/Thread.cxx
+++ b/src/player/Thread.cxx
@@ -37,7 +37,7 @@
 #include "thread/Name.hxx"
 #include "Log.hxx"
 
-#include <stdexcept>
+#include <exception>
 
 #include <string.h>
 
@@ -462,8 +462,8 @@ Player::OpenOutput()
 	try {
 		const ScopeUnlock unlock(pc.mutex);
 		pc.outputs.Open(play_audio_format, buffer);
-	} catch (const std::runtime_error &e) {
-		LogError(e);
+	} catch (...) {
+		LogError(std::current_exception());
 
 		output_open = false;
 
@@ -564,8 +564,8 @@ Player::SendSilence()
 
 	try {
 		pc.outputs.Play(chunk);
-	} catch (const std::runtime_error &e) {
-		LogError(e);
+	} catch (...) {
+		LogError(std::current_exception());
 		buffer.Return(chunk);
 		return false;
 	}
@@ -896,8 +896,8 @@ Player::PlayNextChunk()
 
 	try {
 		play_chunk(pc, *song, chunk, buffer, play_audio_format);
-	} catch (const std::runtime_error &e) {
-		LogError(e);
+	} catch (...) {
+		LogError(std::current_exception());
 
 		buffer.Return(chunk);
 
diff --git a/src/playlist/PlaylistRegistry.cxx b/src/playlist/PlaylistRegistry.cxx
index de143b412..98894bba8 100644
--- a/src/playlist/PlaylistRegistry.cxx
+++ b/src/playlist/PlaylistRegistry.cxx
@@ -38,8 +38,6 @@
 #include "config/ConfigGlobal.hxx"
 #include "config/Block.hxx"
 
-#include <stdexcept>
-
 #include <assert.h>
 #include <string.h>
 
@@ -196,7 +194,7 @@ playlist_list_open_stream_mime2(InputStreamPtr &&is, const char *mime)
 			   fresh start */
 			try {
 				is->LockRewind();
-			} catch (const std::runtime_error &) {
+			} catch (...) {
 			}
 
 			auto playlist = playlist_plugin_open_stream(plugin,
@@ -240,7 +238,7 @@ playlist_list_open_stream_suffix(InputStreamPtr &&is, const char *suffix)
 			   fresh start */
 			try {
 				is->LockRewind();
-			} catch (const std::runtime_error &) {
+			} catch (...) {
 			}
 
 			auto playlist = playlist_plugin_open_stream(plugin,
diff --git a/src/playlist/PlaylistSong.cxx b/src/playlist/PlaylistSong.cxx
index 12cd4bdb0..f3568500c 100644
--- a/src/playlist/PlaylistSong.cxx
+++ b/src/playlist/PlaylistSong.cxx
@@ -26,8 +26,6 @@
 #include "util/UriUtil.hxx"
 #include "DetachedSong.hxx"
 
-#include <stdexcept>
-
 #include <string.h>
 
 static void
@@ -53,7 +51,7 @@ try {
 
 	merge_song_metadata(song, tmp);
 	return true;
-} catch (const std::runtime_error &) {
+} catch (...) {
 	return false;
 }
 
diff --git a/src/playlist/PlaylistStream.cxx b/src/playlist/PlaylistStream.cxx
index fe41eb8b6..34fdc86d6 100644
--- a/src/playlist/PlaylistStream.cxx
+++ b/src/playlist/PlaylistStream.cxx
@@ -26,7 +26,7 @@
 #include "fs/Path.hxx"
 #include "Log.hxx"
 
-#include <stdexcept>
+#include <exception>
 
 #include <assert.h>
 
@@ -46,8 +46,8 @@ try {
 	auto is = OpenLocalInputStream(path, mutex, cond);
 	return playlist_list_open_stream_suffix(std::move(is),
 						suffix_utf8.c_str());
-} catch (const std::runtime_error &e) {
-	LogError(e);
+} catch (...) {
+	LogError(std::current_exception());
 	return nullptr;
 }
 
@@ -64,8 +64,8 @@ try {
 		playlist = playlist_open_path_suffix(path, mutex, cond);
 
 	return playlist;
-} catch (const std::runtime_error &e) {
-	LogError(e);
+} catch (...) {
+	LogError(std::current_exception());
 	return nullptr;
 }
 
@@ -80,7 +80,7 @@ try {
 
 	auto is = InputStream::OpenReady(uri, mutex, cond);
 	return playlist_list_open_stream(std::move(is), uri);
-} catch (const std::runtime_error &e) {
-	LogError(e);
+} catch (...) {
+	LogError(std::current_exception());
 	return nullptr;
 }
diff --git a/src/queue/PlaylistUpdate.cxx b/src/queue/PlaylistUpdate.cxx
index fe6942ecd..a710a0c36 100644
--- a/src/queue/PlaylistUpdate.cxx
+++ b/src/queue/PlaylistUpdate.cxx
@@ -23,8 +23,6 @@
 #include "db/LightSong.hxx"
 #include "DetachedSong.hxx"
 
-#include <stdexcept>
-
 static bool
 UpdatePlaylistSong(const Database &db, DetachedSong &song)
 {
@@ -36,7 +34,7 @@ UpdatePlaylistSong(const Database &db, DetachedSong &song)
 	const LightSong *original;
 	try {
 		original = db.GetSong(song.GetURI());
-	} catch (const std::runtime_error &e) {
+	} catch (...) {
 		/* not found - shouldn't happen, because the update
 		   thread should ensure that all stale Song instances
 		   have been purged */
diff --git a/src/queue/QueueSave.cxx b/src/queue/QueueSave.cxx
index 05d8e2e43..4bfb54072 100644
--- a/src/queue/QueueSave.cxx
+++ b/src/queue/QueueSave.cxx
@@ -29,6 +29,8 @@
 #include "util/StringCompare.hxx"
 #include "Log.hxx"
 
+#include <exception>
+
 #include <stdlib.h>
 
 #define PRIO_LABEL "Prio: "
@@ -96,8 +98,8 @@ queue_load_song(TextFile &file, const SongLoader &loader,
 
 		try {
 			song = song_load(file, uri);
-		} catch (const std::runtime_error &e) {
-			LogError(e);
+		} catch (...) {
+			LogError(std::current_exception());
 			return;
 		}
 	} else {
diff --git a/src/sticker/SongSticker.cxx b/src/sticker/SongSticker.cxx
index 45115251d..0101a1820 100644
--- a/src/sticker/SongSticker.cxx
+++ b/src/sticker/SongSticker.cxx
@@ -25,8 +25,6 @@
 #include "util/Alloc.hxx"
 #include "util/ScopeExit.hxx"
 
-#include <stdexcept>
-
 #include <string.h>
 #include <stdlib.h>
 
@@ -96,7 +94,7 @@ sticker_song_find_cb(const char *uri, const char *value, void *user_data)
 		const LightSong *song = db->GetSong(uri);
 		data->func(*song, value, data->user_data);
 		db->ReturnSong(song);
-	} catch (const std::runtime_error &e) {
+	} catch (...) {
 	}
 }
 
diff --git a/src/storage/CompositeStorage.cxx b/src/storage/CompositeStorage.cxx
index f5f7e1e6b..a04ed1ce9 100644
--- a/src/storage/CompositeStorage.cxx
+++ b/src/storage/CompositeStorage.cxx
@@ -299,7 +299,7 @@ CompositeStorage::OpenDirectory(const char *uri)
 
 	try {
 		other = f.directory->storage->OpenDirectory(f.uri);
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 	}
 
 	return new CompositeDirectoryReader(other, directory->children);
diff --git a/src/storage/plugins/CurlStorage.cxx b/src/storage/plugins/CurlStorage.cxx
index feaa1c37c..caba4579f 100644
--- a/src/storage/plugins/CurlStorage.cxx
+++ b/src/storage/plugins/CurlStorage.cxx
@@ -194,7 +194,7 @@ ParseTimeStamp(const char *s)
 	try {
 		// TODO: make this more robust
 		return ParseTimePoint(s, "%a, %d %b %Y %T %Z");
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 		return std::chrono::system_clock::time_point::min();
 	}
 }
diff --git a/src/storage/plugins/LocalStorage.cxx b/src/storage/plugins/LocalStorage.cxx
index 06da3aaf7..b03981ada 100644
--- a/src/storage/plugins/LocalStorage.cxx
+++ b/src/storage/plugins/LocalStorage.cxx
@@ -123,7 +123,7 @@ LocalStorage::MapFS(const char *uri_utf8) const noexcept
 {
 	try {
 		return MapFSOrThrow(uri_utf8);
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 		return AllocatedPath::Null();
 	}
 }
diff --git a/src/tag/ApeLoader.cxx b/src/tag/ApeLoader.cxx
index caf5ad5c7..15d7b018a 100644
--- a/src/tag/ApeLoader.cxx
+++ b/src/tag/ApeLoader.cxx
@@ -24,7 +24,6 @@
 #include "util/StringView.hxx"
 
 #include <memory>
-#include <stdexcept>
 
 #include <stdint.h>
 #include <assert.h>
@@ -104,6 +103,6 @@ try {
 	}
 
 	return true;
-} catch (const std::runtime_error &) {
-		return false;
+} catch (...) {
+	return false;
 }
diff --git a/src/tag/Generic.cxx b/src/tag/Generic.cxx
index 859f4382b..0d97c9d92 100644
--- a/src/tag/Generic.cxx
+++ b/src/tag/Generic.cxx
@@ -28,7 +28,7 @@
 #include "input/LocalOpen.hxx"
 #include "Log.hxx"
 
-#include <stdexcept>
+#include <exception>
 
 bool
 ScanGenericTags(InputStream &is, const TagHandler &handler, void *ctx)
@@ -39,7 +39,7 @@ ScanGenericTags(InputStream &is, const TagHandler &handler, void *ctx)
 #ifdef ENABLE_ID3TAG
 	try {
 		is.LockRewind();
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 		return false;
 	}
 
@@ -57,7 +57,7 @@ try {
 
 	auto is = OpenLocalInputStream(path, mutex, cond);
 	return ScanGenericTags(*is, handler, ctx);
-} catch (const std::runtime_error &e) {
-	LogError(e);
+} catch (...) {
+	LogError(std::current_exception());
 	return false;
 }
diff --git a/src/tag/Id3Load.cxx b/src/tag/Id3Load.cxx
index fe9ba0b0f..e4234fab6 100644
--- a/src/tag/Id3Load.cxx
+++ b/src/tag/Id3Load.cxx
@@ -27,7 +27,6 @@
 #include <id3tag.h>
 
 #include <algorithm>
-#include <stdexcept>
 
 static constexpr size_t ID3V1_SIZE = 128;
 
@@ -46,7 +45,7 @@ try {
 	is.ReadFull(buf, sizeof(buf));
 
 	return id3_tag_query(buf, sizeof(buf));
-} catch (const std::runtime_error &) {
+} catch (...) {
 	return 0;
 }
 
@@ -77,7 +76,7 @@ try {
 	is.ReadFull(end, remaining);
 
 	return UniqueId3Tag(id3_tag_parse(tag_buffer.get(), tag_size));
-} catch (const std::runtime_error &) {
+} catch (...) {
 	return nullptr;
 }
 
@@ -87,7 +86,7 @@ try {
 	is.Seek(offset);
 
 	return ReadId3Tag(is);
-} catch (const std::runtime_error &) {
+} catch (...) {
 	return nullptr;
 }
 
@@ -98,7 +97,7 @@ try {
 	is.ReadFull(buffer, ID3V1_SIZE);
 
 	return UniqueId3Tag(id3_tag_parse(buffer, ID3V1_SIZE));
-} catch (const std::runtime_error &) {
+} catch (...) {
 	return nullptr;
 }
 
@@ -107,7 +106,7 @@ ReadId3v1Tag(InputStream &is, offset_type offset)
 try {
 	is.Seek(offset);
 	return ReadId3v1Tag(is);
-} catch (const std::runtime_error &) {
+} catch (...) {
 	return nullptr;
 }
 
@@ -140,7 +139,7 @@ try {
 	}
 
 	return tag;
-} catch (const std::runtime_error &) {
+} catch (...) {
 	return nullptr;
 }
 
@@ -181,7 +180,7 @@ try {
 
 	/* We have an id3v2 tag, so ditch v1tag */
 	return tag;
-} catch (const std::runtime_error &) {
+} catch (...) {
 	return nullptr;
 }
 
@@ -191,7 +190,7 @@ try {
 	size_t size;
 	try {
 		size = riff_seek_id3(is);
-	} catch (const std::runtime_error &) {
+	} catch (...) {
 		size = aiff_seek_id3(is);
 	}
 
@@ -203,7 +202,7 @@ try {
 	is.ReadFull(buffer.get(), size);
 
 	return UniqueId3Tag(id3_tag_parse(buffer.get(), size));
-} catch (const std::runtime_error &) {
+} catch (...) {
 	return nullptr;
 }
 
@@ -220,6 +219,6 @@ try {
 	}
 
 	return tag;
-} catch (const std::runtime_error &) {
+} catch (...) {
 	return nullptr;
 }
diff --git a/src/tag/Id3Scan.cxx b/src/tag/Id3Scan.cxx
index db428137d..95479dd25 100644
--- a/src/tag/Id3Scan.cxx
+++ b/src/tag/Id3Scan.cxx
@@ -32,7 +32,7 @@
 #include <id3tag.h>
 
 #include <string>
-#include <stdexcept>
+#include <exception>
 
 #include <string.h>
 #include <stdlib.h>
@@ -349,8 +349,8 @@ tag_id3_scan(InputStream &is,
 		tag = tag_id3_load(is);
 		if (!tag)
 			return false;
-	} catch (const std::runtime_error &e) {
-		LogError(e);
+	} catch (...) {
+		LogError(std::current_exception());
 		return false;
 	}
 
diff --git a/test/FakeDecoderAPI.cxx b/test/FakeDecoderAPI.cxx
index ce915ba1e..c9256708f 100644
--- a/test/FakeDecoderAPI.cxx
+++ b/test/FakeDecoderAPI.cxx
@@ -24,8 +24,6 @@
 #include "util/StringBuffer.hxx"
 #include "Compiler.h"
 
-#include <stdexcept>
-
 #include <unistd.h>
 #include <stdio.h>
 
@@ -83,7 +81,7 @@ FakeDecoder::Read(InputStream &is, void *buffer, size_t length)
 {
 	try {
 		return is.LockRead(buffer, length);
-	} catch (const std::runtime_error &e) {
+	} catch (...) {
 		return 0;
 	}
 }
diff --git a/test/TestIcu.cxx b/test/TestIcu.cxx
index 4c9798d40..33de1fc6c 100644
--- a/test/TestIcu.cxx
+++ b/test/TestIcu.cxx
@@ -43,7 +43,7 @@ public:
 		try {
 			IcuConverter::Create("doesntexist");
 			CPPUNIT_FAIL("Exception expected");
-		} catch (const std::runtime_error &) {
+		} catch (...) {
 		}
 	}
 
@@ -56,7 +56,7 @@ public:
 			try {
 				auto f = converter->FromUTF8(i);
 				CPPUNIT_FAIL("Exception expected");
-			} catch (const std::runtime_error &) {
+			} catch (...) {
 			}
 		}
 
diff --git a/test/run_inotify.cxx b/test/run_inotify.cxx
index 1f7690243..ba653a436 100644
--- a/test/run_inotify.cxx
+++ b/test/run_inotify.cxx
@@ -23,6 +23,8 @@
 #include "event/Loop.hxx"
 #include "Log.hxx"
 
+#include <exception>
+
 #include <sys/inotify.h>
 
 static constexpr unsigned IN_MASK =
@@ -59,7 +61,7 @@ try {
 	event_loop.Run();
 
 	return EXIT_SUCCESS;
-} catch (const std::runtime_error &e) {
-	LogError(e);
+} catch (...) {
+	LogError(std::current_exception());
 	return EXIT_FAILURE;
 }
diff --git a/test/run_resolver.cxx b/test/run_resolver.cxx
index da8ac7292..681d64445 100644
--- a/test/run_resolver.cxx
+++ b/test/run_resolver.cxx
@@ -23,7 +23,7 @@
 #include "net/SocketAddress.hxx"
 #include "Log.hxx"
 
-#include <stdexcept>
+#include <exception>
 
 #ifdef _WIN32
 #include <ws2tcpip.h>
@@ -53,7 +53,7 @@ try {
 
 	freeaddrinfo(ai);
 	return EXIT_SUCCESS;
-} catch (const std::runtime_error &e) {
-	LogError(e);
+} catch (...) {
+	LogError(std::current_exception());
 	return EXIT_FAILURE;
 }