From 29274c1f35b2dcfb6a10606906c220f2948af36f Mon Sep 17 00:00:00 2001 From: wmayer Date: Sat, 26 Apr 2025 13:26:08 +0200 Subject: [PATCH] Gui: Improve auto-saving Handle possibly raised exceptions in RecoveryRunnable::run(). Since the run() method is executed within the context of a worker thread all exceptions must be handled before returning to Qt Concurrent as otherwise the application will be terminated. For testing purposes load the corrupted project file from this forum thread https://forum.freecad.org/viewtopic.php?p=823608#p823608 and wait for the auto-saving. --- src/Gui/AutoSaver.cpp | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/Gui/AutoSaver.cpp b/src/Gui/AutoSaver.cpp index 6228221486..62e76b1001 100644 --- a/src/Gui/AutoSaver.cpp +++ b/src/Gui/AutoSaver.cpp @@ -344,17 +344,28 @@ public: } void run() override { - prop->SaveDocFile(writer); - writer.close(); + try { + prop->SaveDocFile(writer); + writer.close(); - // We could have renamed the file in this thread. However, there is - // still chance of crash when we deleted the original and before rename - // the new file. So we ask the main thread to do it. There is still - // possibility of crash caused by thread other than the main, but - // that's the best we can do for now. - QMetaObject::invokeMethod(AutoSaver::instance(), "renameFile", - Qt::QueuedConnection, Q_ARG(QString,dirName) - ,Q_ARG(QString,fileName),Q_ARG(QString,tmpName)); + // We could have renamed the file in this thread. However, there is + // still chance of crash when we deleted the original and before rename + // the new file. So we ask the main thread to do it. There is still + // possibility of crash caused by thread other than the main, but + // that's the best we can do for now. + QMetaObject::invokeMethod(AutoSaver::instance(), "renameFile", + Qt::QueuedConnection, Q_ARG(QString,dirName) + ,Q_ARG(QString,fileName),Q_ARG(QString,tmpName)); + } + catch (const Base::Exception& e) { + Base::Console().warning("Exception in auto-saving: %s\n", e.what()); + } + catch (const std::exception& e) { + Base::Console().warning("C++ exception in auto-saving: %s\n", e.what()); + } + catch (...) { + Base::Console().warning("Unknown exception in auto-saving\n"); + } } private: