1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-20 22:30:05 +02:00

Save, later rethrow exceptions caught in callbacks from C libraries

This commit is contained in:
Paul Licameli 2018-04-16 17:04:55 -04:00
parent ac373502a9
commit c20aefc10f
3 changed files with 20 additions and 40 deletions

View File

@ -62,8 +62,7 @@ public:
std::unique_ptr<WaveTrack> outputLeftTrack;
std::unique_ptr<WaveTrack> outputRightTrack;
wxFileName failedFileName;
bool error{ false };
std::exception_ptr mpException {};
};
class SBSMSEffectInterface final : public SBSMSInterfaceSliding {
@ -100,23 +99,16 @@ long resampleCB(void *cb_data, SBSMSFrame *data)
// I don't know if we can safely propagate errors through sbsms, and it
// does not seem to let us report error codes, so use this roundabout to
// stop the effect early.
// This would be easier with std::exception_ptr but we don't have that yet.
try {
r->leftTrack->Get(
(samplePtr)(r->leftBuffer.get()), floatSample, r->offset, blockSize);
r->rightTrack->Get(
(samplePtr)(r->rightBuffer.get()), floatSample, r->offset, blockSize);
}
catch ( const FileException& e ) {
if ( e.cause == FileException::Cause::Read )
r->failedFileName = e.fileName;
data->size = 0;
r->error = true;
return 0;
}
catch ( ... ) {
// Save the exception object for re-throw when out of the library
r->mpException = std::current_exception();
data->size = 0;
r->error = true;
return 0;
}
@ -425,15 +417,13 @@ bool EffectSBSMS::Process()
if (TrackProgress(nWhichTrack, frac))
return false;
}
if (rb.failedFileName.IsOk())
// re-construct an exception
// I wish I had std::exception_ptr instead
// and could re-throw any AudacityException
throw FileException{
FileException::Cause::Read, rb.failedFileName };
else if (rb.error)
// well, what?
bGoodResult = false;
{
auto pException = rb.mpException;
rb.mpException = {};
if (pException)
std::rethrow_exception(pException);
}
if (bGoodResult) {
rb.outputLeftTrack->Flush();

View File

@ -967,8 +967,7 @@ bool NyquistEffect::TransferDataFromWindow()
bool NyquistEffect::ProcessOne()
{
mError = false;
mFailedFileName.Clear();
mpException = {};
nyx_rval rval;
@ -1393,15 +1392,12 @@ bool NyquistEffect::ProcessOne()
}
// See if GetCallback found read errors
if (mFailedFileName.IsOk())
// re-construct an exception
// I wish I had std::exception_ptr instead
// and could re-throw any AudacityException
throw FileException{
FileException::Cause::Read, mFailedFileName };
else if (mError)
// what, then?
success = false;
{
auto pException = mpException;
mpException = {};
if (pException)
std::rethrow_exception( pException );
}
if (!success)
return false;
@ -2156,14 +2152,9 @@ int NyquistEffect::GetCallback(float *buffer, int ch,
mCurBuffer[ch].ptr(), floatSample,
mCurBufferStart[ch], mCurBufferLen[ch]);
}
catch ( const FileException& e ) {
if ( e.cause == FileException::Cause::Read )
mFailedFileName = e.fileName;
mError = true;
return -1;
}
catch ( ... ) {
mError = true;
// Save the exception object for re-throw when out of the library
mpException = std::current_exception();
return -1;
}
}

View File

@ -275,8 +275,7 @@ private:
wxTextCtrl *mCommandText;
wxCheckBox *mVersionCheckBox;
bool mError{ false };
wxFileName mFailedFileName;
std::exception_ptr mpException {};
DECLARE_EVENT_TABLE()