-
Notifications
You must be signed in to change notification settings - Fork 38
Expand file tree
/
Copy patherrorwrapper.py
More file actions
133 lines (106 loc) · 4.29 KB
/
errorwrapper.py
File metadata and controls
133 lines (106 loc) · 4.29 KB
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
#!/usr/bin/env python
##############################################################################
#
# PDFgui by DANSE Diffraction group
# Simon J. L. Billinge
# (c) 2008 trustees of the Michigan State University.
# All rights reserved.
#
# File coded by: Chris Farrow
#
# See AUTHORS.txt for a list of people who contributed.
# See LICENSE.txt for license information.
#
##############################################################################
"""This module contains a function wrapper and an object wrapper that
catch control errors and shows them in an error report dialog.
This is used by PDFPanel and MainFrame.
"""
import sys
import traceback
import wx
from diffpy.pdfgui.control.controlerrors import ControlError, TempControlSelectError
from diffpy.pdfgui.gui import pdfguiglobals
from diffpy.pdfgui.gui.errorreportdialog import ErrorReportDialog
from diffpy.pdfgui.gui.errorreportdialog_control_fix import ErrorReportDialogControlFix
# these methods will not be wrapped in catchFunctionErrors
_EXCLUDED_METHODS = dict.fromkeys(dir(wx.Panel) + dir(wx.Dialog))
def catchFunctionErrors(obj, funcName):
"""Wrap a function so its errors get transferred to a dialog.
obj -- Object containing the function. It is assumed that the
object has an attribute named 'mainFrame', which is a
reference to the MainFrame instance, which contains
information about how and when to display errors.
funcName -- Name of a function to wrap.
Returns the wrapped function
"""
func = getattr(obj, funcName)
# do not catch anything when requested in pdfguigloabals.dbopts
if pdfguiglobals.dbopts.noerrordialog:
return func
# default return value when exception is skipped:
rvpass = wx.ID_CANCEL
# otherwise wrap func within exceptions handler
def _f(*args, **kwargs):
hasmf = hasattr(obj, "mainFrame") and obj.mainFrame is not None
try:
return func(*args, **kwargs)
# to be deleted. temporarily used for show the select-control error.
except TempControlSelectError:
dlg = ErrorReportDialogControlFix(obj.mainFrame)
dlg.ShowModal()
dlg.Destroy()
# Display ControlError error messages in a dialog.
except ControlError as e:
if not hasmf:
raise
message = str(e)
obj.mainFrame.showMessage(message, "Oops!")
return rvpass
# Everything else
except Exception:
if pdfguiglobals.dbopts.pythondebugger:
import pdb
tb = sys.exc_info()[2]
pdb.post_mortem(tb)
return rvpass
if not hasmf:
raise
msglines = traceback.format_exception(*sys.exc_info())
message = "".join(msglines)
if obj.mainFrame.quitting:
sys.stderr.write(message)
sys.stderr.write("\n")
else:
dlg = ErrorReportDialog(obj.mainFrame)
dlg.text_ctrl_log.SetValue(message)
dlg.ShowModal()
dlg.Destroy()
return rvpass
# we should never get here
pass
return _f
def catchObjectErrors(obj, exclude=None):
"""Wrap all functions of an object so that the exceptions are
caught.
obj -- Object containing the function. It is assumed that the object has an
attribute named 'mainFrame', which is a reference to the MainFrame
instance, which contains information about how and when to display
errors.
exclude -- An iterable of additional function names to exclude. These are
excluded in addition to names in _EXCLUDED_METHODS defined above.
All functions starting with '_' are excluded.
"""
if exclude:
extra_excludes = dict.fromkeys(exclude)
else:
extra_excludes = {}
funcNames = [
item
for item in dir(obj)
if not item.startswith("_") and item not in _EXCLUDED_METHODS and item not in extra_excludes
]
for name in funcNames:
if hasattr(getattr(obj, name), "__call__"):
setattr(obj, name, catchFunctionErrors(obj, name))
return