diff --git a/src/command/FingerprintCommands.cxx b/src/command/FingerprintCommands.cxx index a4cab902b..30599ec99 100644 --- a/src/command/FingerprintCommands.cxx +++ b/src/command/FingerprintCommands.cxx @@ -305,7 +305,12 @@ GetChromaprintCommand::Read(InputStream &is, void *buffer, size_t length) cond.wait(lock); } - return is.Read(lock, buffer, length); + try { + return is.Read(lock, buffer, length); + } catch (...) { + ChromaprintDecoderClient::error = std::current_exception(); + return 0; + } } CommandResult diff --git a/src/lib/chromaprint/DecoderClient.cxx b/src/lib/chromaprint/DecoderClient.cxx index e99aca07d..262551709 100644 --- a/src/lib/chromaprint/DecoderClient.cxx +++ b/src/lib/chromaprint/DecoderClient.cxx @@ -28,6 +28,9 @@ ChromaprintDecoderClient::~ChromaprintDecoderClient() noexcept = default; void ChromaprintDecoderClient::Finish() { + if (error) + std::rethrow_exception(error); + if (!ready) throw std::runtime_error("Decoding failed"); @@ -86,5 +89,10 @@ ChromaprintDecoderClient::SubmitData(InputStream *, size_t ChromaprintDecoderClient::Read(InputStream &is, void *buffer, size_t length) { - return is.LockRead(buffer, length); + try { + return is.LockRead(buffer, length); + } catch (...) { + error = std::current_exception(); + return 0; + } } diff --git a/src/lib/chromaprint/DecoderClient.hxx b/src/lib/chromaprint/DecoderClient.hxx index b85b9a806..107b623c1 100644 --- a/src/lib/chromaprint/DecoderClient.hxx +++ b/src/lib/chromaprint/DecoderClient.hxx @@ -24,6 +24,7 @@ #include "decoder/Client.hxx" #include "thread/Mutex.hxx" +#include #include #include @@ -39,6 +40,13 @@ class ChromaprintDecoderClient : public DecoderClient { uint64_t remaining_bytes; +protected: + /** + * This is set when an I/O error occurs while decoding; it + * will be rethrown by Finish(). + */ + std::exception_ptr error; + public: Mutex mutex; @@ -63,7 +71,7 @@ public: bool seekable, SignedSongTime duration) override; DecoderCommand GetCommand() noexcept override { - return remaining_bytes > 0 + return !error && remaining_bytes > 0 ? DecoderCommand::NONE : DecoderCommand::STOP; }