1 """GNUmed exception handling widgets."""
2
3 __version__ = "$Revision: 1.17 $"
4 __author__ = "K. Hilbert <Karsten.Hilbert@gmx.net>"
5 __license__ = "GPL (details at http://www.gnu.org)"
6
7 import logging, exceptions, traceback, re as regex, sys, os, shutil, datetime as pyDT, codecs
8
9
10 import wx
11
12
13 from Gnumed.business import gmSurgery
14 from Gnumed.pycommon import gmDispatcher, gmTools, gmCfg2, gmI18N, gmLog2, gmPG2
15 from Gnumed.wxpython import gmGuiHelpers
16 from Gnumed.wxGladeWidgets import wxgUnhandledExceptionDlg
17
18
19 _log2 = logging.getLogger('gm.gui')
20 _log2.info(__version__)
21
22 _prev_excepthook = None
23 application_is_closing = False
24
26 global _client_version
27 _client_version = version
28
30 global _sender_email
31 _sender_email = email
32
34 global _helpdesk
35 _helpdesk = helpdesk
36
38 global _staff_name
39 _staff_name = staff_name
40
42 global _is_public_database
43 _is_public_database = value
44
46
47 _log2.debug('unhandled exception caught:', exc_info = (t, v, tb))
48
49
50 if t == KeyboardInterrupt:
51 print "<Ctrl-C>: Shutting down ..."
52 top_win = wx.GetApp().GetTopWindow()
53 wx.CallAfter(top_win.Close)
54 return
55
56
57 try: wx.EndBusyCursor()
58 except: pass
59
60
61 if application_is_closing:
62
63 if t == wx._core.PyDeadObjectError:
64 return
65 gmLog2.log_stack_trace()
66 return
67
68
69
70 if t == wx._core.PyDeadObjectError:
71 _log2.warning('continuing and hoping for the best')
72 return
73
74
75 if t == exceptions.ImportError:
76 _log2.error('module [%s] not installed', v)
77 gmGuiHelpers.gm_show_error (
78 aTitle = _('Missing GNUmed module'),
79 aMessage = _(
80 'GNUmed detected that parts of it are not\n'
81 'properly installed. The following message\n'
82 'names the missing part:\n'
83 '\n'
84 ' "%s"\n'
85 '\n'
86 'Please make sure to get the missing\n'
87 'parts installed. Otherwise some of the\n'
88 'functionality will not be accessible.'
89 ) % v
90 )
91 return
92
93
94 _cfg = gmCfg2.gmCfgData()
95 if _cfg.get(option = 'debug') is False:
96 _log2.error('enabling debug mode')
97 _cfg.set_option(option = 'debug', value = True)
98 root_logger = logging.getLogger()
99 root_logger.setLevel(logging.DEBUG)
100 _log2.debug('unhandled exception caught:', exc_info = (t, v, tb))
101
102
103 try:
104 msg = gmPG2.extract_msg_from_pg_exception(exc = v)
105 except:
106 msg = u'cannot extract message from PostgreSQL exception'
107 print msg
108 print v
109
110 conn_loss_on_operational_error = (
111 (t == gmPG2.dbapi.OperationalError)
112 and
113 ('erver' in msg)
114 and
115 (('term' in msg) or ('abnorm' in msg) or ('end' in msg))
116 )
117 conn_loss_on_interface_error = (
118 (t == gmPG2.dbapi.InterfaceError)
119 and
120 ('onnect' in msg)
121 and
122 (('close' in msg) or ('end' in msg))
123 )
124 if (conn_loss_on_operational_error or conn_loss_on_interface_error):
125 _log2.error('lost connection')
126 gmLog2.log_stack_trace()
127 gmLog2.flush()
128 gmGuiHelpers.gm_show_error (
129 aTitle = _('Lost connection'),
130 aMessage = _(
131 'Since you were last working in GNUmed,\n'
132 'your database connection timed out.\n'
133 '\n'
134 'This GNUmed session is now expired.\n'
135 '\n'
136 'You will have to close this client and\n'
137 'restart a new GNUmed session.'
138 )
139 )
140 return
141
142 gmLog2.log_stack_trace()
143
144 name = os.path.basename(_logfile_name)
145 name, ext = os.path.splitext(name)
146 new_name = os.path.expanduser(os.path.join (
147 '~',
148 'gnumed',
149 'logs',
150 '%s_%s%s' % (name, pyDT.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'), ext)
151 ))
152
153 dlg = cUnhandledExceptionDlg(parent = None, id = -1, exception = (t, v, tb), logfile = new_name)
154 dlg.ShowModal()
155 comment = dlg._TCTRL_comment.GetValue()
156 dlg.Destroy()
157 if (comment is not None) and (comment.strip() != u''):
158 _log2.error(u'user comment: %s', comment.strip())
159
160 _log2.warning('syncing log file for backup to [%s]', new_name)
161 gmLog2.flush()
162 shutil.copy2(_logfile_name, new_name)
163
185
192
198
200
202
203 exception = kwargs['exception']
204 del kwargs['exception']
205 self.logfile = kwargs['logfile']
206 del kwargs['logfile']
207
208 wxgUnhandledExceptionDlg.wxgUnhandledExceptionDlg.__init__(self, *args, **kwargs)
209
210 if _sender_email is not None:
211 self._TCTRL_sender.SetValue(_sender_email)
212 self._TCTRL_helpdesk.SetValue(_helpdesk)
213 self._TCTRL_logfile.SetValue(self.logfile)
214 t, v, tb = exception
215 self._TCTRL_exc_type.SetValue(str(t))
216 self._TCTRL_exc_value.SetValue(str(v))
217 self._TCTRL_traceback.SetValue(''.join(traceback.format_tb(tb)))
218
219 self.Fit()
220
231
374
380
381