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:
parent
ac373502a9
commit
c20aefc10f
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -275,8 +275,7 @@ private:
|
||||
wxTextCtrl *mCommandText;
|
||||
wxCheckBox *mVersionCheckBox;
|
||||
|
||||
bool mError{ false };
|
||||
wxFileName mFailedFileName;
|
||||
std::exception_ptr mpException {};
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user