From 1924c1d804c0b1f03d405d4dda6e92d622f64744 Mon Sep 17 00:00:00 2001 From: Martchus Date: Sun, 13 Nov 2016 22:57:02 +0100 Subject: [PATCH] Handle unexpected exceptions when parsing/making * Don't just ignore exception (previous behavior) * Add critical notification * Show results, though error (to ease debugging) --- cli/mainfeatures.cpp | 4 ++-- gui/tageditorwidget.cpp | 52 +++++++++++++++++++++++++++-------------- 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/cli/mainfeatures.cpp b/cli/mainfeatures.cpp index 81dc1da..cae91a0 100644 --- a/cli/mainfeatures.cpp +++ b/cli/mainfeatures.cpp @@ -317,9 +317,9 @@ uint64 parseUInt64(const Argument &arg, uint64 defaultValue) if(arg.isPresent()) { try { if(*arg.values().front() == '0' && *(arg.values().front() + 1) == 'x') { - return stringToNumber(arg.values().front() + 2, 16); + return stringToNumber(arg.values().front() + 2, 16); } else { - return stringToNumber(arg.values().front()); + return stringToNumber(arg.values().front()); } } catch(const ConversionException &) { cerr << "Warning: The specified value \"" << arg.values().front() << "\" is no valid unsigned integer and will be ignored." << endl; diff --git a/gui/tageditorwidget.cpp b/gui/tageditorwidget.cpp index 07eb557..ce71575 100644 --- a/gui/tageditorwidget.cpp +++ b/gui/tageditorwidget.cpp @@ -752,26 +752,34 @@ bool TagEditorWidget::startParsing(const QString &path, bool forceRefresh) auto startThread = [this] { m_fileOperationMutex.lock(); char result; - try { + try { // credits for this nesting go to GCC regression 66145 try { - // try to open with write access - m_fileInfo.reopen(false); + try { + // try to open with write access + m_fileInfo.reopen(false); + } catch(...) { + ::IoUtilities::catchIoFailure(); + // try to open read-only if opening with write access failed + m_fileInfo.reopen(true); + } + m_fileInfo.setForceFullParse(Settings::values().editor.forceFullParse); + m_fileInfo.parseEverything(); + result = ParsingSuccessful; + } catch(const Failure &) { + // the file has been opened; parsing notifications will be shown in the info box + result = FatalParsingError; } catch(...) { ::IoUtilities::catchIoFailure(); - // try to open read-only if opening with write access failed - m_fileInfo.reopen(true); + // the file could not be opened because an IO error occured + m_fileInfo.close(); // ensure file is closed + result = IoError; } - m_fileInfo.setForceFullParse(Settings::values().editor.forceFullParse); - m_fileInfo.parseEverything(); - result = ParsingSuccessful; - } catch(const Failure &) { - // the file has been opened; parsing notifications will be shown in the info box + } catch(const exception &e) { + m_fileInfo.addNotification(Media::NotificationType::Critical, string("Something completely unexpected happened: ") + e.what(), "parsing"); result = FatalParsingError; } catch(...) { - ::IoUtilities::catchIoFailure(); - // the file could not be opened because an IO error occured - m_fileInfo.close(); // ensure file is closed - result = IoError; + m_fileInfo.addNotification(Media::NotificationType::Critical, "Something completely unexpected happened", "parsing"); + result = FatalParsingError; } m_fileInfo.unregisterAllCallbacks(); QMetaObject::invokeMethod(this, "showFile", Qt::QueuedConnection, Q_ARG(char, result)); @@ -1080,12 +1088,20 @@ bool TagEditorWidget::startSaving() m_fileOperationMutex.lock(); bool processingError = false, ioError = false; try { - m_fileInfo.applyChanges(); - } catch(const Failure &) { + try { + m_fileInfo.applyChanges(); + } catch(const Failure &) { + processingError = true; + } catch(...) { + ::IoUtilities::catchIoFailure(); + ioError = true; + } + } catch(const exception &e) { + m_fileInfo.addNotification(Media::NotificationType::Critical, string("Something completely unexpected happened: ") + e.what(), "making"); processingError = true; } catch(...) { - ::IoUtilities::catchIoFailure(); - ioError = true; + m_fileInfo.addNotification(Media::NotificationType::Critical, "Something completely unexpected happened", "making"); + processingError = true; } m_fileInfo.unregisterAllCallbacks(); QMetaObject::invokeMethod(this, "showSavingResult", Qt::QueuedConnection, Q_ARG(bool, processingError), Q_ARG(bool, ioError));