"""
novelWriter – Exception Handling
================================
Error handling function and error dialog
File History:
Created: 2020-08-02 [0.10.2]
This file is a part of novelWriter
Copyright 2018–2023, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see
An unhandled error has been encountered.
" "Please report this error by submitting an issue report on " "GitHub, providing a description and including the error " "message and traceback shown below.
" f"URL: {nwConst.URL_REPORT}
" ) try: kernelVersion = QSysInfo.kernelVersion() except Exception: kernelVersion = "Unknown" try: import lxml lxmlVersion = lxml.__version__ # type: ignore except Exception: lxmlVersion = "Unknown" try: import enchant enchantVersion = enchant.__version__ except Exception: enchantVersion = "Unknown" try: exTrace = "\n".join(format_tb(exTrace)) self.msgBody.setPlainText(( "Environment:\n" f"novelWriter Version: {__version__}\n" f"Host OS: {sys.platform} ({kernelVersion})\n" f"Python: {sys.version.split()[0]} ({sys.hexversion:#x})\n" f"Qt: {QT_VERSION_STR}, PyQt: {PYQT_VERSION_STR}\n" f"lxml: {lxmlVersion}\n" f"enchant: {enchantVersion}\n\n" f"{exType.__name__}:\n{str(exValue)}\n\n" f"Traceback:\n{exTrace}\n" )) except Exception: self.msgBody.setPlainText("Failed to generate error report ...") return ## # Slots ## def _doClose(self): """Close the dialog. """ self.close() return # END Class NWErrorMessage def exceptionHandler(exType, exValue, exTrace): """Function to catch unhandled global exceptions. """ from traceback import print_tb from PyQt5.QtWidgets import qApp logger.critical("%s: %s", exType.__name__, str(exValue)) print_tb(exTrace) try: nwGUI = None for qWin in qApp.topLevelWidgets(): if qWin.objectName() == "GuiMain": nwGUI = qWin break if nwGUI is None: logger.warning("Could not find main GUI window so cannot open error dialog") return errMsg = NWErrorMessage(nwGUI) errMsg.setMessage(exType, exValue, exTrace) errMsg.exec_() try: # Try a controlled shutdown nwGUI.closeProject(isYes=True) # type: ignore nwGUI.closeMain() # type: ignore logger.info("Emergency shutdown successful") except Exception as exc: logger.critical("Could not close the project before exiting") logger.critical(formatException(exc)) qApp.exit(1) except Exception as exc: logger.critical(formatException(exc)) return