diff --git a/src/BlockFile.cpp b/src/BlockFile.cpp index 8f5bb6ee8..abea90982 100644 --- a/src/BlockFile.cpp +++ b/src/BlockFile.cpp @@ -616,8 +616,7 @@ size_t BlockFile::CommonReadData( if ( framesRead < len ) { if (mayThrow) - //throw FileException{ FileException::Cause::Read, fileName } - ; + throw FileException{ FileException::Cause::Read, fileName }; ClearSamples(data, format, framesRead, len - framesRead); } diff --git a/src/DirManager.cpp b/src/DirManager.cpp index 44afdd9b7..33058030a 100644 --- a/src/DirManager.cpp +++ b/src/DirManager.cpp @@ -90,6 +90,7 @@ #include "AudacityApp.h" #include "AudacityException.h" #include "BlockFile.h" +#include "FileException.h" #include "blockfile/LegacyBlockFile.h" #include "blockfile/LegacyAliasBlockFile.h" #include "blockfile/SimpleBlockFile.h" @@ -97,6 +98,7 @@ #include "blockfile/PCMAliasBlockFile.h" #include "blockfile/ODPCMAliasBlockFile.h" #include "blockfile/ODDecodeBlockFile.h" +#include "InconsistencyException.h" #include "Internat.h" #include "Project.h" #include "Prefs.h" @@ -1110,8 +1112,12 @@ bool DirManager::ContainsBlockFile(const wxString &filepath) const // Adds one to the reference count of the block file, // UNLESS it is "locked", then it makes a NEW copy of // the BlockFile. +// This function returns non-NULL, or else throws BlockFilePtr DirManager::CopyBlockFile(const BlockFilePtr &b) { + if (!b) + THROW_INCONSISTENCY_EXCEPTION; + auto result = b->GetFileName(); const auto &fn = result.name; @@ -1122,7 +1128,7 @@ BlockFilePtr DirManager::CopyBlockFile(const BlockFilePtr &b) // // LLL: Except for silent block files which have uninitialized filename. if (fn.IsOk()) - mBlockFileHash[fn.GetName()]=b; + mBlockFileHash[fn.GetName()] = b; return b; } @@ -1148,7 +1154,9 @@ BlockFilePtr DirManager::CopyBlockFile(const BlockFilePtr &b) { if( !wxCopyFile(fn.GetFullPath(), newFile.GetFullPath()) ) - return {}; + // Disk space exhaustion, maybe + throw FileException{ + FileException::Cause::Write, newFile }; } // Done with fn @@ -1156,13 +1164,13 @@ BlockFilePtr DirManager::CopyBlockFile(const BlockFilePtr &b) b2 = b->Copy(std::move(newFile)); - if (b2 == NULL) - return {}; - - mBlockFileHash[newName]=b2; + mBlockFileHash[newName] = b2; aliasList.Add(newPath); } + if (!b2) + THROW_INCONSISTENCY_EXCEPTION; + return b2; } diff --git a/src/DirManager.h b/src/DirManager.h index 55b2e8b76..6eb731377 100644 --- a/src/DirManager.h +++ b/src/DirManager.h @@ -95,6 +95,8 @@ class PROFILE_DLL_API DirManager final : public XMLTagHandler { // Adds one to the reference count of the block file, // UNLESS it is "locked", then it makes a NEW copy of // the BlockFile. + // May throw an exception in case of disk space exhaustion, otherwise + // returns non-null. BlockFilePtr CopyBlockFile(const BlockFilePtr &b); BlockFile *LoadBlockFile(const wxChar **attrs, sampleFormat format); diff --git a/src/NoteTrack.cpp b/src/NoteTrack.cpp index 746765cd9..0f46a6541 100644 --- a/src/NoteTrack.cpp +++ b/src/NoteTrack.cpp @@ -16,6 +16,7 @@ #include "Audacity.h" #include "NoteTrack.h" +#include "Experimental.h" #include #include @@ -33,7 +34,7 @@ #include "Prefs.h" #include "effects/TimeWarper.h" -#include "Experimental.h" +#include "InconsistencyException.h" #ifdef SONIFY #include "portmidi.h" @@ -435,8 +436,8 @@ int NoteTrack::GetVisibleChannels() Track::Holder NoteTrack::Cut(double t0, double t1) { if (t1 <= t0) - //THROW_INCONSISTENCY_EXCEPTION - ; + THROW_INCONSISTENCY_EXCEPTION; + double len = t1-t0; auto newTrack = std::make_unique(mDirManager); @@ -458,8 +459,8 @@ Track::Holder NoteTrack::Cut(double t0, double t1) Track::Holder NoteTrack::Copy(double t0, double t1, bool) const { if (t1 <= t0) - //THROW_INCONSISTENCY_EXCEPTION - ; + THROW_INCONSISTENCY_EXCEPTION; + double len = t1-t0; auto newTrack = std::make_unique(mDirManager); @@ -494,10 +495,9 @@ bool NoteTrack::Trim(double t0, double t1) void NoteTrack::Clear(double t0, double t1) { - // If t1 = t0, should Clear return true? if (t1 <= t0) - // THROW_INCONSISTENCY_EXCEPTION; ? - return; + THROW_INCONSISTENCY_EXCEPTION; + double len = t1-t0; if (mSeq) diff --git a/src/Sequence.cpp b/src/Sequence.cpp index 7a6237a53..a51ac3524 100644 --- a/src/Sequence.cpp +++ b/src/Sequence.cpp @@ -441,8 +441,7 @@ void Sequence::Paste(sampleCount s, const Sequence *src) // PRL: Why bother with Internat when the above is just wxT? Internat::ToString(s.as_double(), 0).c_str(), Internat::ToString(mNumSamples.as_double(), 0).c_str()); - //THROW_INCONSISTENCY_EXCEPTION - ; + THROW_INCONSISTENCY_EXCEPTION; } // Quick check to make sure that it doesn't overflow @@ -453,8 +452,7 @@ void Sequence::Paste(sampleCount s, const Sequence *src) // PRL: Why bother with Internat when the above is just wxT? Internat::ToString(mNumSamples.as_double(), 0).c_str(), Internat::ToString(src->mNumSamples.as_double(), 0).c_str()); - //THROW_INCONSISTENCY_EXCEPTION - ; + THROW_INCONSISTENCY_EXCEPTION; } if (src->mSampleFormat != mSampleFormat) @@ -462,8 +460,7 @@ void Sequence::Paste(sampleCount s, const Sequence *src) wxLogError( wxT("Sequence::Paste: Sample format to be pasted, %s, does not match destination format, %s."), GetSampleFormatStr(src->mSampleFormat), GetSampleFormatStr(src->mSampleFormat)); - //THROW_INCONSISTENCY_EXCEPTION - ; + THROW_INCONSISTENCY_EXCEPTION; } const BlockArray &srcBlock = src->mBlock; @@ -607,11 +604,7 @@ void Sequence::Paste(sampleCount s, const Sequence *src) for (i = 2; i < srcNumBlocks - 2; i++) { const SeqBlock &block = srcBlock[i]; auto file = mDirManager->CopyBlockFile(block.f); - if (!file) { - wxASSERT(false); // TODO: Handle this better, alert the user of failure. - return; - } - + // We can assume file is not null newBlock.push_back(SeqBlock(file, block.start + s)); } @@ -645,8 +638,7 @@ void Sequence::InsertSilence(sampleCount s0, sampleCount len) { // Quick check to make sure that it doesn't overflow if (Overflows((mNumSamples.as_double()) + (len.as_double()))) - //THROW_INCONSISTENCY_EXCEPTION - ; + THROW_INCONSISTENCY_EXCEPTION; if (len <= 0) return; @@ -696,8 +688,7 @@ void Sequence::AppendAlias(const wxString &fullPath, { // Quick check to make sure that it doesn't overflow if (Overflows((mNumSamples.as_double()) + ((double)len))) - //THROW_INCONSISTENCY_EXCEPTION - ; + THROW_INCONSISTENCY_EXCEPTION; SeqBlock newBlock( useOD? @@ -715,8 +706,7 @@ void Sequence::AppendCoded(const wxString &fName, sampleCount start, { // Quick check to make sure that it doesn't overflow if (Overflows((mNumSamples.as_double()) + ((double)len))) - //THROW_INCONSISTENCY_EXCEPTION - ; + THROW_INCONSISTENCY_EXCEPTION; SeqBlock newBlock( mDirManager->NewODDecodeBlockFile(fName, start, len, channel, decodeType), @@ -732,19 +722,13 @@ void Sequence::AppendBlock { // Quick check to make sure that it doesn't overflow if (Overflows((mNumSamples.as_double()) + ((double)b.f->GetLength()))) - // THROW_INCONSISTENCY_EXCEPTION - return - ; + THROW_INCONSISTENCY_EXCEPTION; SeqBlock newBlock( mDirManager.CopyBlockFile(b.f), // Bump ref count if not locked, else copy mNumSamples ); - if (!newBlock.f) { - /// \todo Error Could not paste! (Out of disk space?) - wxASSERT(false); // TODO: Handle this better, alert the user of failure. - return; - } + // We can assume newBlock.f is not null mBlock.push_back(newBlock); mNumSamples += newBlock.f->GetLength(); @@ -1137,8 +1121,7 @@ bool Sequence::Get(samplePtr buffer, sampleFormat format, if (start < 0 || start > mNumSamples || start + len > mNumSamples) { if (mayThrow) - //THROW_INCONSISTENCY_EXCEPTION - ; + THROW_INCONSISTENCY_EXCEPTION; ClearSamples( buffer, floatSample, 0, len ); return false; } @@ -1176,8 +1159,7 @@ void Sequence::SetSamples(samplePtr buffer, sampleFormat format, { if (start < 0 || start >= mNumSamples || start + len > mNumSamples) - //THROW_INCONSISTENCY_EXCEPTION - ; + THROW_INCONSISTENCY_EXCEPTION; SampleBuffer scratch(mMaxSamples, mSampleFormat); @@ -1213,9 +1195,7 @@ void Sequence::SetSamples(samplePtr buffer, sampleFormat format, if (!(fileLength <= mMaxSamples && bstart + blen <= fileLength)) - //THROW_INCONSISTENCY_EXCEPTION - wxASSERT(false) - ; + THROW_INCONSISTENCY_EXCEPTION; if ( bstart > 0 || blen < fileLength ) { Read(scratch.ptr(), mSampleFormat, block, 0, fileLength, true); @@ -1527,8 +1507,7 @@ void Sequence::Append(samplePtr buffer, sampleFormat format, // Quick check to make sure that it doesn't overflow if (Overflows(mNumSamples.as_double() + ((double)len))) - //THROW_INCONSISTENCY_EXCEPTION - ; + THROW_INCONSISTENCY_EXCEPTION; BlockArray newBlock; sampleCount newNumSamples = mNumSamples; @@ -1644,8 +1623,7 @@ void Sequence::Delete(sampleCount start, sampleCount len) return; if (len < 0 || start < 0 || start >= mNumSamples) - //THROW_INCONSISTENCY_EXCEPTION - ; + THROW_INCONSISTENCY_EXCEPTION; //TODO: add a ref-deref mechanism to SeqBlock/BlockArray so we don't have to make this a critical section. //On-demand threads iterate over the mBlocks and the GUI thread deletes them, so for now put a mutex here over @@ -1858,8 +1836,7 @@ void Sequence::ConsistencyCheck wxT("Undo the failed operation(s), then export or save your work and quit.")); if (mayThrow) - //throw ex - ; + throw ex; else wxASSERT(false); } diff --git a/src/Sequence.h b/src/Sequence.h index 7309d0f8d..f264aff08 100644 --- a/src/Sequence.h +++ b/src/Sequence.h @@ -103,6 +103,7 @@ class PROFILE_DLL_API Sequence final : public XMLTagHandler{ bool GetWaveDisplay(float *min, float *max, float *rms, int* bl, size_t len, const sampleCount *where) const; + // Return non-null, or else throw! std::unique_ptr Copy(sampleCount s0, sampleCount s1) const; void Paste(sampleCount s0, const Sequence *src); diff --git a/src/WaveClip.cpp b/src/WaveClip.cpp index a214090db..71923696f 100644 --- a/src/WaveClip.cpp +++ b/src/WaveClip.cpp @@ -1298,8 +1298,7 @@ std::pair WaveClip::GetMinMax( { if (t0 > t1) { if (mayThrow) - //THROW_INCONSISTENCY_EXCEPTION - ; + THROW_INCONSISTENCY_EXCEPTION; return { 0.f, // harmless, but unused since Sequence::GetMinMax does not use these values 0.f // harmless, but unused since Sequence::GetMinMax does not use these values @@ -1321,8 +1320,7 @@ float WaveClip::GetRMS(double t0, double t1, bool mayThrow) const { if (t0 > t1) { if (mayThrow) - //THROW_INCONSISTENCY_EXCEPTION - ; + THROW_INCONSISTENCY_EXCEPTION; return 0.f; } @@ -1783,10 +1781,8 @@ void WaveClip::ExpandCutLine(double cutLinePosition) [=](const WaveClipHolder &p) { return p.get() == cutline; }); if (it != end) mCutLines.erase(it); // deletes cutline! - else { - // THROW_INCONSISTENCY_EXCEPTION; - wxASSERT(false); - } + else + THROW_INCONSISTENCY_EXCEPTION; } } @@ -1906,13 +1902,14 @@ void WaveClip::Resample(int rate, ProgressDialog *progress) ); error = (updateResult != ProgressResult::Success); if (error) - break; - //throw UserException{}; + throw UserException{}; } } if (error) - ; + throw SimpleMessageBoxException{ + _("Resampling failed.") + }; else { // Use NOFAIL-GUARANTEE in these steps diff --git a/src/WaveTrack.cpp b/src/WaveTrack.cpp index ffc12a8c4..ef320012d 100644 --- a/src/WaveTrack.cpp +++ b/src/WaveTrack.cpp @@ -555,8 +555,7 @@ bool WaveTrack::IsEmpty(double t0, double t1) const Track::Holder WaveTrack::Cut(double t0, double t1) { if (t1 < t0) - // THROW_INCONSISTENCY_EXCEPTION - ; + THROW_INCONSISTENCY_EXCEPTION; auto tmp = Copy(t0, t1); @@ -569,8 +568,7 @@ Track::Holder WaveTrack::SplitCut(double t0, double t1) // STRONG-GUARANTEE { if (t1 < t0) - //THROW_INCONSISTENCY_EXCEPTION - ; + THROW_INCONSISTENCY_EXCEPTION; // SplitCut is the same as 'Copy', then 'SplitDelete' auto tmp = Copy(t0, t1); @@ -584,15 +582,12 @@ Track::Holder WaveTrack::SplitCut(double t0, double t1) Track::Holder WaveTrack::CutAndAddCutLine(double t0, double t1) { if (t1 < t0) - //THROW_INCONSISTENCY_EXCEPTION - ; + THROW_INCONSISTENCY_EXCEPTION; // Cut is the same as 'Copy', then 'Delete' auto tmp = Copy(t0, t1); - if (!ClearAndAddCutLine(t0, t1)) - //THROW_INCONSISTENCY_EXCEPTION - ; + ClearAndAddCutLine(t0, t1); return tmp; } @@ -648,8 +643,7 @@ void WaveTrack::Trim (double t0, double t1) Track::Holder WaveTrack::Copy(double t0, double t1, bool forClipboard) const { if (t1 <= t0) - //THROW_INCONSISTENCY_EXCEPTION - ; + THROW_INCONSISTENCY_EXCEPTION; WaveTrack *newTrack; Track::Holder result @@ -1038,8 +1032,7 @@ void WaveTrack::HandleClear(double t0, double t1, // STRONG-GUARANTEE { if (t1 < t0) - // THROW_INCONSISTENCY_EXCEPTION; // ? - return; + THROW_INCONSISTENCY_EXCEPTION; bool editClipCanMove = true; gPrefs->Read(wxT("/GUI/EditClipCanMove"), &editClipCanMove); @@ -1221,12 +1214,10 @@ void WaveTrack::SyncLockAdjust(double oldT1, double newT1) // follow EditClipCanMove rules (Paste() does it right) AudacityProject *p = GetActiveProject(); if (!p) - // THROW_INCONSISTENCY_EXCEPTION - ; + THROW_INCONSISTENCY_EXCEPTION; TrackFactory *f = p->GetTrackFactory(); if (!f) - // THROW_INCONSISTENCY_EXCEPTION - ; + THROW_INCONSISTENCY_EXCEPTION; auto tmp = f->NewWaveTrack(GetSampleFormat(), GetRate()); tmp->InsertSilence(0.0, newT1 - oldT1); @@ -1395,8 +1386,7 @@ void WaveTrack::Paste(double t0, const Track *src) void WaveTrack::Silence(double t0, double t1) { if (t1 < t0) - // THROW_INCONSISTENCY_EXCEPTION; // ? - return; + THROW_INCONSISTENCY_EXCEPTION; auto start = (sampleCount)floor(t0 * mRate + 0.5); auto len = (sampleCount)floor(t1 * mRate + 0.5) - start; @@ -1432,8 +1422,7 @@ void WaveTrack::InsertSilence(double t, double len) // STRONG-GUARANTEE { if (len <= 0) - // THROW_INCONSISTENCY_EXCEPTION; // ? - return; + THROW_INCONSISTENCY_EXCEPTION; if (mClips.empty()) { @@ -1953,8 +1942,7 @@ std::pair WaveTrack::GetMinMax( if (t0 > t1) { if (mayThrow) - //THROW_INCONSISTENCY_EXCEPTION - ; + THROW_INCONSISTENCY_EXCEPTION; return results; } @@ -1986,8 +1974,7 @@ float WaveTrack::GetRMS(double t0, double t1, bool mayThrow) const { if (t0 > t1) { if (mayThrow) - //THROW_INCONSISTENCY_EXCEPTION - ; + THROW_INCONSISTENCY_EXCEPTION; return 0.f; } diff --git a/src/blockfile/ODDecodeBlockFile.cpp b/src/blockfile/ODDecodeBlockFile.cpp index 141e57742..406f0d762 100644 --- a/src/blockfile/ODDecodeBlockFile.cpp +++ b/src/blockfile/ODDecodeBlockFile.cpp @@ -27,6 +27,7 @@ The summary is eventually computed and written to a file in a background thread. #include #include +#include "../FileException.h" #include "../FileFormats.h" #include "../Internat.h" #include "NotYetAvailableException.h" @@ -38,8 +39,9 @@ char bheaderTag[bheaderTagLen + 1] = "AudacityBlockFile112"; /// Create a disk file and write summary and sample data to it ODDecodeBlockFile::ODDecodeBlockFile(wxFileNameWrapper &&baseFileName, wxFileNameWrapper &&audioFileName, sampleCount aliasStart, - size_t aliasLen, int aliasChannel,unsigned int decodeType): - SimpleBlockFile{ std::move(baseFileName), + size_t aliasLen, int aliasChannel,unsigned int decodeType) +try + : SimpleBlockFile{ std::move(baseFileName), NULL, aliasLen, floatSample, true, true }, //floatSample has no effect. last two bools - bypass writing of blockfile and cache @@ -51,6 +53,14 @@ ODDecodeBlockFile::ODDecodeBlockFile(wxFileNameWrapper &&baseFileName, wxFileNam mAudioFileName = std::move(audioFileName); mFormat = int16Sample; } +catch ( const FileException & e ) +{ + // The constructor SimpleBlockFile sometimes throws this, + // but it never will for the arguments that were passed to it here. + // So add a catch for completeness, but just assert that this won't happen. + wxASSERT(false); + throw; +} /// Create the memory structure to refer to the given block file ODDecodeBlockFile::ODDecodeBlockFile(wxFileNameWrapper &&existingFile, wxFileNameWrapper &&audioFileName, sampleCount aliasStart, @@ -102,8 +112,7 @@ auto ODDecodeBlockFile::GetMinMaxRMS( else { if (mayThrow) - // throw NotYetAvailableException{ mAudioFileName } - ; + throw NotYetAvailableException{ mAudioFileName }; //fake values. These values are used usually for normalization and amplifying, so we want //the max to be maximal and the min to be minimal @@ -123,8 +132,7 @@ auto ODDecodeBlockFile::GetMinMaxRMS(bool mayThrow) const -> MinMaxRMS else { if (mayThrow) - // throw NotYetAvailableException{ mAudioFileName } - ; + throw NotYetAvailableException{ mAudioFileName }; //fake values. These values are used usually for normalization and amplifying, so we want //the max to be maximal and the min to be minimal @@ -446,8 +454,7 @@ size_t ODDecodeBlockFile::ReadData(samplePtr data, sampleFormat format, else { if (mayThrow) - //throw NotYetAvailableException{ mFileName } - ; + throw NotYetAvailableException{ mAudioFileName }; //we should do an ODRequest to start processing the data here, and wait till it finishes. and just do a SimpleBlockFile //ReadData. diff --git a/src/blockfile/ODPCMAliasBlockFile.cpp b/src/blockfile/ODPCMAliasBlockFile.cpp index 62f468559..375bd9ca6 100644 --- a/src/blockfile/ODPCMAliasBlockFile.cpp +++ b/src/blockfile/ODPCMAliasBlockFile.cpp @@ -133,8 +133,7 @@ auto ODPCMAliasBlockFile::GetMinMaxRMS( else { if (mayThrow) - //throw NotYetAvailableException{ GetAliasedFileName() } - ; + throw NotYetAvailableException{ GetAliasedFileName() }; //fake values. These values are used usually for normalization and amplifying, so we want //the max to be maximal and the min to be minimal @@ -156,8 +155,7 @@ auto ODPCMAliasBlockFile::GetMinMaxRMS(bool mayThrow) const -> MinMaxRMS else { if (mayThrow) - //throw NotYetAvailableException{ GetAliasedFileName() } - ; + throw NotYetAvailableException{ GetAliasedFileName() }; //fake values. These values are used usually for normalization and amplifying, so we want //the max to be maximal and the min to be minimal @@ -415,9 +413,8 @@ void ODPCMAliasBlockFile::WriteSummary() //and wxLog calls are not thread safe. printf("Unable to write summary data to file: %s", fileNameChar.get()); - // throw FileException{ - // FileException::Cause::Read, wxFileName{ fileNameChar.get() } }; - return; + throw FileException{ + FileException::Cause::Read, wxFileName{ fileNameChar.get() } }; } ArrayOf cleanup; diff --git a/src/blockfile/SimpleBlockFile.cpp b/src/blockfile/SimpleBlockFile.cpp index 9b3923a8b..ae6bd133b 100644 --- a/src/blockfile/SimpleBlockFile.cpp +++ b/src/blockfile/SimpleBlockFile.cpp @@ -57,15 +57,18 @@ to get its definition, rather than rolling our own. *//*******************************************************************/ +#include "../Audacity.h" +#include "SimpleBlockFile.h" + #include #include #include #include #include +#include "../FileException.h" #include "../Prefs.h" -#include "SimpleBlockFile.h" #include "../FileFormats.h" #include "sndfile.h" @@ -114,8 +117,9 @@ SimpleBlockFile::SimpleBlockFile(wxFileNameWrapper &&baseFileName, if (!(allowDeferredWrite && useCache) && !bypassCache) { bool bSuccess = WriteSimpleBlockFile(sampleData, sampleLen, format, NULL); - wxASSERT(bSuccess); // TODO: Handle failure here by alert to user and undo partial op. - wxUnusedVar(bSuccess); + if (!bSuccess) + throw FileException{ + FileException::Cause::Write, GetFileName().name }; } if (useCache) { @@ -404,8 +408,7 @@ size_t SimpleBlockFile::ReadData(samplePtr data, sampleFormat format, if ( framesRead < len ) { if (mayThrow) // Not the best exception class? - //throw FileException{ FileException::Cause::Read, mFileName } - ; + throw FileException{ FileException::Cause::Read, mFileName }; ClearSamples(data, format, framesRead, len - framesRead); } diff --git a/src/import/ImportRaw.cpp b/src/import/ImportRaw.cpp index 5cbdf348f..854d4d6b6 100644 --- a/src/import/ImportRaw.cpp +++ b/src/import/ImportRaw.cpp @@ -27,10 +27,12 @@ and sample size to help you importing data of an unknown format. #include "Import.h" #include "../DirManager.h" +#include "../FileException.h" #include "../FileFormats.h" #include "../Internat.h" #include "../Prefs.h" #include "../ShuttleGui.h" +#include "../UserException.h" #include "../WaveTrack.h" #include @@ -92,6 +94,9 @@ class ImportRawDialog final : public wxDialogWrapper { DECLARE_EVENT_TABLE() }; +// This function leaves outTracks empty as an indication of error, +// but may also throw FileException to make use of the application's +// user visible error reporting. void ImportRaw(wxWindow *parent, const wxString &fileName, TrackFactory *trackFactory, TrackHolders &outTracks) { @@ -158,12 +163,11 @@ void ImportRaw(wxWindow *parent, const wxString &fileName, } if (!sndFile){ - // TODO: Handle error char str[1000]; sf_error_str((SNDFILE *)NULL, str, 1000); printf("%s\n", str); - return; + throw FileException{ FileException::Cause::Open, fileName }; } result = sf_command(sndFile.get(), SFC_SET_RAW_START_OFFSET, &offset, sizeof(offset)); @@ -171,6 +175,8 @@ void ImportRaw(wxWindow *parent, const wxString &fileName, char str[1000]; sf_error_str(sndFile.get(), str, 1000); printf("%s\n", str); + + throw FileException{ FileException::Cause::Read, fileName }; } SFCall(sf_seek, sndFile.get(), 0, SEEK_SET); @@ -254,9 +260,7 @@ void ImportRaw(wxWindow *parent, const wxString &fileName, else { // This is not supposed to happen, sndfile.h says result is always // a count, not an invalid value for error - wxASSERT(false); - updateResult = ProgressResult::Failed; - break; + throw FileException{ FileException::Cause::Read, fileName }; } if (block) { @@ -288,10 +292,8 @@ void ImportRaw(wxWindow *parent, const wxString &fileName, } while (block > 0 && framescompleted < totalFrames); } - if (updateResult == ProgressResult::Failed || updateResult == ProgressResult::Cancelled) { - // It's a shame we can't return proper error code - return; - } + if (updateResult == ProgressResult::Failed || updateResult == ProgressResult::Cancelled) + throw UserException{}; for (const auto &channel : channels) channel->Flush();