Files
LorenEteval_Furious/Furious/Utility/Process.py
T
2023-07-24 19:49:17 +08:00

86 lines
2.4 KiB
Python

from Furious.Widget.Application import Application
from Furious.Utility.Constants import PLATFORM, CRASH_LOG_DIR
from PySide6.QtWidgets import QApplication
import os
import sys
import logging
import datetime
import traceback
import functools
import multiprocessing
logger = logging.getLogger(__name__)
if PLATFORM == 'Windows':
ProcessContext = multiprocessing
else:
ProcessContext = multiprocessing.get_context('spawn')
class Process(ProcessContext.Process):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.startUpTime = str(datetime.datetime.now()).replace(':', '')
self.logFileName = f'{self.startUpTime}.log'
self.fileWritten = multiprocessing.Manager().Value('b', False)
self.application = None
def exceptHook(self, exceptionType, exceptionValue, tb):
if logger.level < logging.CRITICAL:
traceback.print_exception(exceptionType, exceptionValue, tb)
if isinstance(exceptionValue, AssertionError):
error = Application.ErrorCode.AssertionError
else:
error = Application.ErrorCode.UnknownException
logger.error(f'stopped with exitcode {error}')
self.saveCrashLog(exceptionType, exceptionValue, tb)
if QApplication.instance() is not None:
QApplication.instance().exit(error)
else:
sys.exit(error)
def saveCrashLog(self, exceptionType, exceptionValue, tb):
try:
os.mkdir(CRASH_LOG_DIR)
except FileExistsError:
# Directory already exists
pass
except Exception:
# Any non-exit exceptions
return
try:
stackLog = functools.reduce(
lambda x, y: x + y,
traceback.format_exception(exceptionType, exceptionValue, tb),
)
if QApplication.instance() is None:
crashLog = f'{stackLog}'
else:
crashLog = f'{QApplication.instance().log()}\n{stackLog}'
with open(CRASH_LOG_DIR / self.logFileName, 'w', encoding='utf-8') as file:
file.write(crashLog)
self.fileWritten.value = True
except Exception:
# Any non-exit exceptions
pass
def run(self):
sys.excepthook = self.exceptHook
self.application = Application(sys.argv)
sys.exit(self.application.run())