Skip to content

Commit

Permalink
Finish pulling all the cruft out of pyfa.py relating to logging and e…
Browse files Browse the repository at this point in the history
…rror handling. All that is now done in separate areas.

Also finally did some major reworking on the error dialog. Now it doesn't spawn a new wxApp and wxFrame for each and every error - attaches to MainFrame and sticks around, having exceptions append to it rather than spawn a new one. In the case that an error happens before MainFrame is available, it spins up a new wxApp. Yay cleanup!
  • Loading branch information
blitzmann committed Nov 26, 2017
1 parent 1da127c commit c000b19
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 293 deletions.
114 changes: 113 additions & 1 deletion config.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import os
import sys

from logbook import Logger
from logbook import CRITICAL, DEBUG, ERROR, FingersCrossedHandler, INFO, Logger, NestedSetup, NullHandler, \
StreamHandler, TimedRotatingFileHandler, WARNING

pyfalog = Logger(__name__)

Expand Down Expand Up @@ -30,6 +31,16 @@
saveDB = None
gameDB = None
logPath = None
loggingLevel = None
logging_setup = None

LOGLEVEL_MAP = {
"critical": CRITICAL,
"error": ERROR,
"warning": WARNING,
"info": INFO,
"debug": DEBUG,
}


def isFrozen():
Expand Down Expand Up @@ -68,6 +79,7 @@ def defPaths(customSavePath=None):
global saveDB
global gameDB
global saveInRoot
global logPath

pyfalog.debug("Configuring Pyfa")

Expand Down Expand Up @@ -106,6 +118,13 @@ def defPaths(customSavePath=None):
if not gameDB:
gameDB = os.path.join(pyfaPath, "eve.db")

if debug:
logFile = "pyfa_debug.log"
else:
logFile = "pyfa.log"

logPath = os.path.join(savePath, logFile)

# DON'T MODIFY ANYTHING BELOW
import eos.config

Expand All @@ -121,3 +140,96 @@ def defPaths(customSavePath=None):
# initialize the settings
from service.settings import EOSSettings
eos.config.settings = EOSSettings.getInstance().EOSSettings # this is kind of confusing, but whatever

def defLogging():
global debug
global logPath
global loggingLevel
global logging_setup

try:
if debug:
logging_setup = NestedSetup([
# make sure we never bubble up to the stderr handler
# if we run out of setup handling
NullHandler(),
StreamHandler(
sys.stdout,
bubble=False,
level=loggingLevel
),
TimedRotatingFileHandler(
logPath,
level=0,
backup_count=3,
bubble=True,
date_format='%Y-%m-%d',
),
])
else:
logging_setup = NestedSetup([
# make sure we never bubble up to the stderr handler
# if we run out of setup handling
NullHandler(),
FingersCrossedHandler(
TimedRotatingFileHandler(
logPath,
level=0,
backup_count=3,
bubble=False,
date_format='%Y-%m-%d',
),
action_level=ERROR,
buffer_size=1000,
# pull_information=True,
# reset=False,
)
])
except:
print("Critical error attempting to setup logging. Falling back to console only.")
logging_setup = NestedSetup([
# make sure we never bubble up to the stderr handler
# if we run out of setup handling
NullHandler(),
StreamHandler(
sys.stdout,
bubble=False
)
])

with logging_setup.threadbound():

# Output all stdout (print) messages as warnings
try:
sys.stdout = LoggerWriter(pyfalog.warning)
except:
pyfalog.critical("Cannot redirect. Continuing without writing stdout to log.")

# Output all stderr (stacktrace) messages as critical
try:
sys.stderr = LoggerWriter(pyfalog.critical)
except:
pyfalog.critical("Cannot redirect. Continuing without writing stderr to log.")


class LoggerWriter(object):
def __init__(self, level):
# self.level is really like using log.debug(message)
# at least in my case
self.level = level

def write(self, message):
# if statement reduces the amount of newlines that are
# printed to the logger
if message.strip() != '':
self.level(message.replace("\n", ""))

def flush(self):
# create a flush method so things can be flushed when
# the system wants to. Not sure if simply 'printing'
# sys.stderr is the correct way to do it, but it seemed
# to work properly for me.
self.level(sys.stderr)



121 changes: 44 additions & 77 deletions gui/errorDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,48 +18,50 @@
# ===============================================================================

# import platform
# import sys
import sys
#
# # noinspection PyPackageRequirements
# import wx
#
# try:
# import config
# except:
# config = None
#
# try:
# import sqlalchemy
#
# sqlalchemy_version = sqlalchemy.__version__
# except:
# sqlalchemy_version = "Unknown"
#
# try:
# from logbook import __version__ as logbook_version
# except:
# logbook_version = "Unknown"
#
# import wx.lib.agw.hyperlink
# noinspection PyPackageRequirements
import wx
import traceback
import config
from logbook import Logger
from service.prereqsCheck import version_block

pyfalog = Logger(__name__)

class ErrorFrameHandler(object):
__app = None

class ErrorHandler(object):
__parent = None
__frame = None

@classmethod
def HandleException(cls, exc_type, exc_value, exc_traceback):
print("Handle excpetion! {}".format(cls.__app))
with config.logging_setup.threadbound():
# Print the base level traceback
t = traceback.format_exception(exc_type, exc_value, exc_traceback)
pyfalog.critical("\n\n"+"".join(t))

if cls.__parent is None:
app = wx.App(False)
ErrorFrame(None)
app.MainLoop()
sys.exit()
else:
if not cls.__frame:
cls.__frame = ErrorFrame(cls.__parent)
cls.__frame.Show()
cls.__frame.addException("".join(t))

@classmethod
def SetApp(cls, wxApp):
cls.__app = wxApp
def SetParent(cls, parent):
cls.__parent = parent


class ErrorFrame(wx.Frame):
def __init__(self, exception=None, tb=None, error_title='Error!'):
def __init__(self, parent=None, error_title='Error!'):
v = sys.version_info

wx.Frame.__init__(self, None, id=wx.ID_ANY, title="pyfa error", pos=wx.DefaultPosition, size=wx.Size(500, 600),
wx.Frame.__init__(self, parent, id=wx.ID_ANY, title="pyfa error", pos=wx.DefaultPosition, size=wx.Size(500, 600),
style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER | wx.STAY_ON_TOP)

desc = "pyfa has experienced an unexpected issue. Below is a message that contains crucial\n" \
Expand Down Expand Up @@ -96,59 +98,24 @@ def __init__(self, exception=None, tb=None, error_title='Error!'):

# mainSizer.AddSpacer((0, 5), 0, wx.EXPAND, 5)

errorTextCtrl = wx.TextCtrl(self, wx.ID_ANY, "", wx.DefaultPosition, (-1, 400), wx.TE_MULTILINE | wx.TE_READONLY | wx.TE_RICH2 | wx.TE_DONTWRAP)
errorTextCtrl.SetFont(wx.Font(8, wx.FONTFAMILY_TELETYPE, wx.NORMAL, wx.NORMAL))
mainSizer.Add(errorTextCtrl, 0, wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, 5)

# try:
# errorTextCtrl.AppendText("OS version: \t" + str(platform.platform()))
# except:
# errorTextCtrl.AppendText("OS version: Unknown")
# errorTextCtrl.AppendText("\n")
#
# try:
# errorTextCtrl.AppendText("Python: \t" + '{}.{}.{}'.format(v.major, v.minor, v.micro))
# except:
# errorTextCtrl.AppendText("Python: Unknown")
# errorTextCtrl.AppendText("\n")
#
# try:
# errorTextCtrl.AppendText("wxPython: \t" + wx.VERSION_STRING)
# except:
# errorTextCtrl.AppendText("wxPython: Unknown")
# errorTextCtrl.AppendText("\n")
#
# errorTextCtrl.AppendText("SQLAlchemy: \t" + str(sqlalchemy_version))
# errorTextCtrl.AppendText("\n")
#
# errorTextCtrl.AppendText("Logbook: \t" + str(logbook_version))
# errorTextCtrl.AppendText("\n")
#
# try:
# errorTextCtrl.AppendText("pyfa version: {0} {1} - {2} {3}".format(config.version, config.tag, config.expansionName, config.expansionVersion))
# except:
# errorTextCtrl.AppendText("pyfa version: Unknown")
# errorTextCtrl.AppendText('\n')
#
# errorTextCtrl.AppendText("pyfa root: " + str(config.pyfaPath or "Unknown"))
# errorTextCtrl.AppendText('\n')
# errorTextCtrl.AppendText("save path: " + str(config.savePath or "Unknown"))
# errorTextCtrl.AppendText('\n')
# errorTextCtrl.AppendText("fs encoding: " + str(sys.getfilesystemencoding() or "Unknown"))
# errorTextCtrl.AppendText('\n\n')

errorTextCtrl.AppendText("EXCEPTION: " + str(exception or "Unknown"))
errorTextCtrl.AppendText('\n\n')

if tb:
for line in tb:
errorTextCtrl.AppendText(line)
errorTextCtrl.Layout()
self.errorTextCtrl = wx.TextCtrl(self, wx.ID_ANY, version_block.strip(), wx.DefaultPosition, (-1, 400), wx.TE_MULTILINE | wx.TE_READONLY | wx.TE_RICH2 | wx.TE_DONTWRAP)
self.errorTextCtrl.SetFont(wx.Font(8, wx.FONTFAMILY_TELETYPE, wx.NORMAL, wx.NORMAL))
mainSizer.Add(self.errorTextCtrl, 0, wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, 5)
self.errorTextCtrl.AppendText("\n")
self.errorTextCtrl.Layout()

self.SetSizer(mainSizer)
mainSizer.Layout()
self.Layout()

self.Centre(wx.BOTH)
self.Bind(wx.EVT_CLOSE, self.OnClose)

self.Show()


def OnClose(self, evt):
self.Hide()

def addException(self, text):
self.errorTextCtrl.AppendText("\n{}\n\n{}".format("#" * 20, text))
Loading

0 comments on commit c000b19

Please sign in to comment.