1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
# -*- coding: utf-8 -*-
import traceback
from DisplayCAL import config
from DisplayCAL.config import fs_enc
from DisplayCAL.log import logbuffer
from DisplayCAL.meta import name as appname, wx_recversion
from DisplayCAL.options import debug
from DisplayCAL.util_str import box
wxEventTypes = {}
def getevtobjname(event, window=None):
"""Get and return the event object's name."""
try:
event_object = event.GetEventObject()
if not event_object and window:
event_object = window.FindWindowById(event.GetId())
if event_object and hasattr(event_object, "GetName"):
return event_object.GetName()
except Exception:
pass
def getevttype(event):
"""Get and return the event object's type."""
if not wxEventTypes:
from DisplayCAL.wxaddons import wx
try:
for name in dir(wx):
if name.find("EVT_") == 0:
attr = getattr(wx, name)
if hasattr(attr, "evtType"):
wxEventTypes[attr.evtType[0]] = name
except Exception:
pass
typeId = event.GetEventType()
if typeId in wxEventTypes:
return wxEventTypes[typeId]
def handle_error(error, parent=None, silent=False, tb=True):
"""Log an error string and show an error dialog."""
traceback.print_exc()
if isinstance(error, tuple):
# We got a tuple. Assume (etype, value, tb)
tbstr = "".join(traceback.format_exception(*error))
error = error[1]
else:
tbstr = traceback.format_exc()
if (
tb
and tbstr.strip() != "None"
and isinstance(error, Exception)
and (
debug
or not isinstance(error, EnvironmentError)
or not getattr(error, "filename", None)
)
):
# Print a traceback if in debug mode, for non environment errors, and
# for environment errors not related to files
errstr, tbstr = (str(v) for v in (error, tbstr))
msg = "\n\n".join((errstr, tbstr))
if msg.startswith(errstr):
print(box(tbstr))
else:
print(box(msg))
else:
msg = str(error)
print(box(msg))
if not silent:
try:
from DisplayCAL.wxaddons import wx
if wx.VERSION < wx_recversion:
msg += (
"\n\nWARNING: Your version of wxPython (%s) is outdated "
"and no longer supported. You should consider updating "
"to wxPython %s or newer."
% (wx.__version__, ".".join(str(n) for n in wx_recversion))
)
app = wx.GetApp()
if app is None and parent is None:
app = wx.App(redirect=False)
# wxPython 3 bugfix: We also need a toplevel window
frame = wx.Frame(None)
parent = False
else:
frame = None
if parent is None:
parent = wx.GetActiveWindow()
if parent:
try:
parent.IsShownOnScreen()
except Exception:
# If the parent is still being constructed, we can't use it
parent = None
icon = wx.ICON_INFORMATION
if not isinstance(error, Info):
if isinstance(error, Warning):
icon = wx.ICON_WARNING
elif isinstance(error, Exception):
icon = wx.ICON_ERROR
dlg = wx.MessageDialog(
(
parent
if parent not in (False, None) and parent.IsShownOnScreen()
else None
),
msg,
app.AppName,
wx.OK | icon,
)
if frame:
# wxPython 3 bugfix: We need to use CallLater and MainLoop
wx.CallLater(1, dlg.ShowModal)
wx.CallLater(1, frame.Close)
app.MainLoop()
else:
dlg.ShowModal()
dlg.Destroy()
except Exception as exception:
traceback.print_exc()
print("Warning: handle_error():", str(exception))
def print_callstack():
"""Print call stack"""
import inspect
stack = inspect.stack()
indent = ""
for _frame, filename, linenum, funcname, line, _exc in reversed(stack[1:]):
print(indent, funcname, filename, linenum, repr("".join(line).strip()))
indent += " "
class ResourceError(Exception):
pass
class Error(Exception):
pass
class Info(UserWarning):
pass
class UnloggedError(Error):
pass
class UnloggedInfo(Info):
pass
class UnloggedWarning(UserWarning):
pass
class DownloadError(Error):
def __init__(self, *args):
Error.__init__(self, *args[:-1])
self.url = args[1]
class UntracedError(Error):
pass
class Warn(UserWarning):
pass
|