Skip to content

Commit 5263e6f

Browse files
doogie99claude
andcommitted
fix(core): don't terminate on exceptions escaping background tasks
Worker threads only caught std::bad_alloc; any other exception thrown during page processing unwound to QThread's start wrapper and aborted the whole application via std::terminate(). Catch std::exception in LoadFileTask and surface it as an in-app error page, and add catch-all safety nets in WorkerThreadPool and BackgroundExecutor. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 5eaac18 commit 5263e6f

3 files changed

Lines changed: 26 additions & 4 deletions

File tree

src/core/BackgroundExecutor.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ void BackgroundExecutor::Dispatcher::customEvent(QEvent* event) {
7575
}
7676
} catch (const std::bad_alloc&) {
7777
OutOfMemoryHandler::instance().handleOutOfMemorySituation();
78+
} catch (const std::exception& e) {
79+
// An exception escaping the executor thread would terminate the application.
80+
qWarning("Background task failed: %s", e.what());
81+
} catch (...) {
82+
qWarning("Background task failed with an unknown exception.");
7883
}
7984
}
8085

src/core/LoadFileTask.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,15 @@ using namespace imageproc;
2626
class LoadFileTask::ErrorResult : public FilterResult {
2727
Q_DECLARE_TR_FUNCTIONS(LoadFileTask)
2828
public:
29-
explicit ErrorResult(const QString& filePath);
29+
explicit ErrorResult(const QString& filePath, const QString& errorDetails = QString());
3030

3131
void updateUI(FilterUiInterface* ui) override;
3232

3333
std::shared_ptr<AbstractFilter> filter() override { return nullptr; }
3434

3535
private:
3636
QString m_filePath;
37+
QString m_errorDetails;
3738
bool m_fileExists;
3839
};
3940

@@ -71,6 +72,12 @@ FilterResultPtr LoadFileTask::operator()() {
7172
}
7273
} catch (const CancelledException&) {
7374
return nullptr;
75+
} catch (const std::bad_alloc&) {
76+
throw; // Handled by the out-of-memory machinery in WorkerThreadPool.
77+
} catch (const std::exception& e) {
78+
// Without this, the exception would escape the worker thread and abort
79+
// the application via std::terminate().
80+
return std::make_shared<ErrorResult>(m_imageId.filePath(), QString::fromUtf8(e.what()));
7481
}
7582
}
7683

@@ -108,8 +115,10 @@ void LoadFileTask::convertToSupportedFormat(QImage& image) const {
108115

109116
/*======================= LoadFileTask::ErrorResult ======================*/
110117

111-
LoadFileTask::ErrorResult::ErrorResult(const QString& filePath)
112-
: m_filePath(QDir::toNativeSeparators(filePath)), m_fileExists(QFile::exists(filePath)) {}
118+
LoadFileTask::ErrorResult::ErrorResult(const QString& filePath, const QString& errorDetails)
119+
: m_filePath(QDir::toNativeSeparators(filePath)),
120+
m_errorDetails(errorDetails),
121+
m_fileExists(QFile::exists(filePath)) {}
113122

114123
void LoadFileTask::ErrorResult::updateUI(FilterUiInterface* ui) {
115124
class ErrWidget : public ErrorWidget {
@@ -128,7 +137,10 @@ void LoadFileTask::ErrorResult::updateUI(FilterUiInterface* ui) {
128137

129138
QString errMsg;
130139
Qt::TextFormat fmt = Qt::AutoText;
131-
if (m_fileExists) {
140+
if (!m_errorDetails.isEmpty()) {
141+
errMsg = tr("An error occurred while processing this page:\n%1\n\nFile: %2").arg(m_errorDetails, m_filePath);
142+
fmt = Qt::PlainText;
143+
} else if (m_fileExists) {
132144
errMsg = tr("The following file could not be loaded:\n%1").arg(m_filePath);
133145
fmt = Qt::PlainText;
134146
} else {

src/core/WorkerThreadPool.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ void WorkerThreadPool::submitTask(const BackgroundTaskPtr& task) {
5757
}
5858
} catch (const std::bad_alloc&) {
5959
OutOfMemoryHandler::instance().handleOutOfMemorySituation();
60+
} catch (const std::exception& e) {
61+
// An exception escaping run() would terminate the application.
62+
qWarning("Background task failed: %s", e.what());
63+
} catch (...) {
64+
qWarning("Background task failed with an unknown exception.");
6065
}
6166
}
6267

0 commit comments

Comments
 (0)