diff --git a/src/AudacityException.h b/src/AudacityException.h index 278536878..8d86dcc0e 100644 --- a/src/AudacityException.h +++ b/src/AudacityException.h @@ -18,6 +18,7 @@ #include "MemoryX.h" #include +#include #include "Internat.h" @@ -105,29 +106,6 @@ struct DefaultDelayedHandlerAction } }; -// Helpers for defining GuardedCall: - -// Call one function object, -// then another unless the first throws, return result of first -template struct Sequencer { - template - R operator () (const F1 &f1, Argument &&a, const F2 &f2) - { - auto result = f1( std::forward(a) ); - f2(); - return result; - } -}; -// template specialization to allow R to be void -template <> struct Sequencer { - template - void operator () (const F1 &f1, Argument &&a, const F2 &f2) - { - f1( std::forward(a) ); - f2(); - } -}; - // Classes that can supply the second argument of GuardedCall: // Frequently useful converter of all exceptions to some failure constant template struct SimpleGuard @@ -169,11 +147,11 @@ inline SimpleGuard< void > MakeSimpleGuard() { return {}; } * for the guarded call or throw the same or another exception. * It executes in the same thread as the body. * - * If the handler catches non-null and does not throw, then delayedHandler + * If the handler is passed non-null and does not throw, then delayedHandler * executes later in the main thread, in idle time of the event loop. */ template < - typename R, // return type + typename R = void, // return type typename F1, // function object with signature R() @@ -190,15 +168,18 @@ R GuardedCall { try { return body(); } catch ( AudacityException &e ) { - return Sequencer{}( handler, &e, - [&] { + + auto end = finally([&]{ + if (!std::uncaught_exception()) { auto pException = std::shared_ptr< AudacityException > { e.Move().release() }; wxTheApp->CallAfter( [=] { // capture pException by value delayedHandler( pException.get() ); } ); } - ); + }); + + return handler( &e ); } catch ( ... ) { return handler( nullptr ); diff --git a/src/AudioIO.cpp b/src/AudioIO.cpp index e451c9f6e..5a65e84c6 100644 --- a/src/AudioIO.cpp +++ b/src/AudioIO.cpp @@ -2724,7 +2724,7 @@ void AudioIO::StopStream() // If the other track operations fail their strong guarantees, then // the shift for latency correction may be skipped. - GuardedCall( [&] { + GuardedCall( [&] { WaveTrack* track = mCaptureTracks[i].get(); // use NOFAIL-GUARANTEE that track is flushed, @@ -3976,7 +3976,7 @@ void AudioIO::FillBuffers() if (!mRecordingException && mCaptureTracks.size() > 0) - GuardedCall( [&] { + GuardedCall( [&] { // start record buffering auto commonlyAvail = GetCommonlyAvailCapture(); diff --git a/src/DirManager.cpp b/src/DirManager.cpp index f79953f88..8fcbfc47b 100644 --- a/src/DirManager.cpp +++ b/src/DirManager.cpp @@ -1660,7 +1660,7 @@ _("Project check of \"%s\" folder \ // and don't try to recover other files but // silence them too. GuardedCall will cause an appropriate // error message for the user. - GuardedCall( + GuardedCall( [&] { ab->Recover(); }, [&] (AudacityException*) { action = 1; } ); @@ -1726,7 +1726,7 @@ _("Project check of \"%s\" folder \ // and don't try to recover other files but // silence them too. GuardedCall will cause an appropriate // error message for the user. - GuardedCall( + GuardedCall( [&] { b->Recover(); nResult |= FSCKstatus_CHANGED; @@ -1800,7 +1800,7 @@ _("Project check of \"%s\" folder \ // and don't try to recover other files but // silence them too. GuardedCall will cause an appropriate // error message for the user. - GuardedCall( + GuardedCall( [&] { //regenerate with zeroes b->Recover(); diff --git a/src/Project.cpp b/src/Project.cpp index 8946a0a7d..be27b6674 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -502,7 +502,7 @@ bool ImportXMLTagHandler::HandleXMLTag(const wxChar *tag, const wxChar **attrs) // Guard this call so that C++ exceptions don't propagate through // the expat library - GuardedCall< void >( + GuardedCall( [&] { mProject->Import(strAttr, &trackArray); }, [&] (AudacityException*) { trackArray.clear(); } ); diff --git a/src/Tags.cpp b/src/Tags.cpp index eeda23bf9..21702864c 100644 --- a/src/Tags.cpp +++ b/src/Tags.cpp @@ -1239,7 +1239,7 @@ void TagsEditor::OnSave(wxCommandEvent & WXUNUSED(event)) return; } - GuardedCall< void >( [&] { + GuardedCall( [&] { // Create/Open the file XMLFileWriter writer{ fn, _("Error Saving Tags File") }; diff --git a/src/effects/Effect.cpp b/src/effects/Effect.cpp index eca3d7d49..1eed69969 100644 --- a/src/effects/Effect.cpp +++ b/src/effects/Effect.cpp @@ -2513,7 +2513,7 @@ void Effect::Preview(bool dryOnly) // was called. if (!dryOnly) { End(); - GuardedCall< void >( [&]{ Init(); } ); + GuardedCall( [&]{ Init(); } ); } if (FocusDialog) { diff --git a/src/effects/Equalization.cpp b/src/effects/Equalization.cpp index 7fc852703..732e0a3c7 100644 --- a/src/effects/Equalization.cpp +++ b/src/effects/Equalization.cpp @@ -1600,7 +1600,7 @@ void EffectEqualization::SaveCurves(const wxString &fileName) else fn = fileName; - GuardedCall< void >( [&] { + GuardedCall( [&] { // Create/Open the file const wxString fullPath{ fn.GetFullPath() }; XMLFileWriter eqFile{ fullPath, _("Error Saving Equalization Curves") }; diff --git a/src/export/ExportFFmpegDialogs.cpp b/src/export/ExportFFmpegDialogs.cpp index 994e45ce9..00bb0f850 100644 --- a/src/export/ExportFFmpegDialogs.cpp +++ b/src/export/ExportFFmpegDialogs.cpp @@ -494,7 +494,7 @@ FFmpegPresets::FFmpegPresets() FFmpegPresets::~FFmpegPresets() { // We're in a destructor! Don't let exceptions out! - GuardedCall< void >( [&] { + GuardedCall( [&] { wxFileName xmlFileName{ FileNames::DataDir(), wxT("ffmpeg_presets.xml") }; XMLFileWriter writer{ xmlFileName.GetFullPath(), _("Error Saving FFmpeg Presets") }; @@ -520,7 +520,7 @@ void FFmpegPresets::ImportPresets(wxString &filename) void FFmpegPresets::ExportPresets(wxString &filename) { - GuardedCall< void >( [&] { + GuardedCall( [&] { XMLFileWriter writer{ filename, _("Error Saving FFmpeg Presets") }; WriteXMLHeader(writer); WriteXML(writer); diff --git a/src/export/ExportMultiple.cpp b/src/export/ExportMultiple.cpp index 97cdc8beb..ff47732f7 100644 --- a/src/export/ExportMultiple.cpp +++ b/src/export/ExportMultiple.cpp @@ -585,7 +585,7 @@ void ExportMultiple::OnExport(wxCommandEvent& WXUNUSED(event)) FileList += '\n'; } - GuardedCall( [&] { + GuardedCall( [&] { // This results dialog is a child of this dialog. HelpSystem::ShowInfoDialog( this, _("Export Multiple"), diff --git a/src/prefs/KeyConfigPrefs.cpp b/src/prefs/KeyConfigPrefs.cpp index d09d0f658..ce9b0b281 100644 --- a/src/prefs/KeyConfigPrefs.cpp +++ b/src/prefs/KeyConfigPrefs.cpp @@ -377,7 +377,7 @@ void KeyConfigPrefs::OnExport(wxCommandEvent & WXUNUSED(event)) return; } - GuardedCall< void >( [&] { + GuardedCall( [&] { XMLFileWriter prefFile{ file, _("Error Exporting Keyboard Shortcuts") }; mManager->WriteXML(prefFile); prefFile.Commit(); diff --git a/src/xml/XMLWriter.cpp b/src/xml/XMLWriter.cpp index 8247cbc38..76b9ac362 100644 --- a/src/xml/XMLWriter.cpp +++ b/src/xml/XMLWriter.cpp @@ -329,7 +329,7 @@ XMLFileWriter::XMLFileWriter XMLFileWriter::~XMLFileWriter() { // Don't let a destructor throw! - GuardedCall< void >( [&] { + GuardedCall( [&] { if (!mCommitted) { auto fileName = GetName(); if ( IsOpened() )