Update of /cvsroot/pywin32/pywin32/Pythonwin
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18996
Modified Files:
win32thread.cpp win32ui.h win32uimodule.cpp win32virt.cpp
Log Message:
[ 977399 ] Support for user supplied exception handler
Index: win32ui.h
===================================================================
RCS file: /cvsroot/pywin32/pywin32/Pythonwin/win32ui.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** win32ui.h 6 Dec 1999 01:13:50 -0000 1.2
--- win32ui.h 7 Oct 2004 08:45:24 -0000 1.3
***************
*** 239,242 ****
--- 239,252 ----
};
+ enum EnumExceptionHandlerAction {
+ EHA_PRINT_ERROR,
+ EHA_DISPLAY_DIALOG
+ };
+
+ typedef void (*ExceptionHandlerFunc)(int action, const char *context, const char *extraTitleMsg);
+
+ PYW_EXPORT void ExceptionHandler(int action, const char *context=NULL, const char *extraTitleMsg=NULL);
+ PYW_EXPORT ExceptionHandlerFunc SetExceptionHandler(ExceptionHandlerFunc handler);
+
// A helper class for calling "virtual methods" - ie, given a C++ object
// call a Python method of that name on the attached Python object.
Index: win32uimodule.cpp
===================================================================
RCS file: /cvsroot/pywin32/pywin32/Pythonwin/win32uimodule.cpp,v
retrieving revision 1.28
retrieving revision 1.29
diff -C2 -d -r1.28 -r1.29
*** win32uimodule.cpp 8 Sep 2004 23:31:12 -0000 1.28
--- win32uimodule.cpp 7 Oct 2004 08:45:24 -0000 1.29
***************
*** 50,53 ****
--- 50,59 ----
static char BASED_CODE errorName[] = "win32ui";
+ // We can't init exceptionHandler in initwin32ui because the application using
+ // us could have called SetExceptionHandler earlier. We do a forward declaration
+ // of DefaultExceptionHandler here and assign it to exceptionHandler.
+ void DefaultExceptionHandler(int action, const char *context, const char *extraTitleMsg);
+ static ExceptionHandlerFunc exceptionHandler = DefaultExceptionHandler;
+
PYW_EXPORT PyObject *ui_module_error;
Win32uiHostGlue *pHostGlue = NULL;
***************
*** 612,619 ****
v = PyRun_String((char *)command, file_input, d, d);
if (v == NULL) {
! PyObject *type, *value, *traceback;
! PyErr_Fetch(&type, &value, &traceback);
! DisplayPythonTraceback(type, value, traceback);
! PyErr_Restore(type, value, traceback);
/*******
PyObject *fo = PyFile_FromString((char *)logFileName, "w" );
--- 618,622 ----
v = PyRun_String((char *)command, file_input, d, d);
if (v == NULL) {
! ExceptionHandler(EHA_DISPLAY_DIALOG);
/*******
PyObject *fo = PyFile_FromString((char *)logFileName, "w" );
***************
*** 701,726 ****
// basic recursion control.
static BOOL bInError = FALSE;
! if (bInError) return;
bInError=TRUE;
! // Check if the exception is SystemExit - if so,
! // PyErr_Print will terminate then and there! This is
! // not good (and not what we want!?
! PyObject *exception, *v, *tb;
! PyErr_Fetch(&exception, &v, &tb);
! PyErr_NormalizeException(&exception, &v, &tb);
! if (exception && PyErr_GivenExceptionMatches(exception, PyExc_SystemExit)) {
! // Replace it with a RuntimeError.
! TRACE("WARNING!! win32ui had a SystemError - Replacing with RuntimeError!!\n");
! Py_DECREF(exception);
! Py_XINCREF(PyExc_RuntimeError);
! PyErr_Restore(PyExc_RuntimeError, v, tb);
! } else
! PyErr_Restore(exception, v, tb);
! // Now print it.
! PyErr_Print();
! bInError=FALSE;
}
--- 704,765 ----
// basic recursion control.
static BOOL bInError = FALSE;
! if (bInError) {
! TRACE("gui_print_error: recursive call!\n");
! return;
! }
bInError=TRUE;
+ ExceptionHandler(EHA_PRINT_ERROR);
+ bInError=FALSE;
+ }
! void DefaultExceptionHandler(int action, const char *context, const char *extraTitleMsg)
! {
! PyObject *type, *value, *traceback;
! PyErr_Fetch(&type, &value, &traceback);
! if (!type) {
! TRACE("DefaultExceptionHandler: no exception occured!\n");
! return;
! }
! if (action == EHA_PRINT_ERROR)
! {
! // Check if the exception is SystemExit - if so,
! // PyErr_Print will terminate then and there! This is
! // not good (and not what we want!?
! PyErr_NormalizeException(&type, &value, &traceback);
! if (type && PyErr_GivenExceptionMatches(type, PyExc_SystemExit)) {
! // Replace it with a RuntimeError.
! TRACE("WARNING!! win32ui had a SystemError - Replacing with RuntimeError!!\n");
! Py_DECREF(type);
! Py_XINCREF(PyExc_RuntimeError);
! PyErr_Restore(PyExc_RuntimeError, value, traceback);
! } else
! PyErr_Restore(type, value, traceback);
! fprintf(stderr, "%s\n", context);
! // Now print it.
! PyErr_Print();
! }
! else if (action == EHA_DISPLAY_DIALOG)
! {
! DisplayPythonTraceback(type, value, traceback, extraTitleMsg);
! PyErr_Restore(type, value, traceback);
! }
! else
! TRACE("DefaultExceptionHandler: unknown action (%d)\n", action);
! }
! void ExceptionHandler(int action, const char *context, const char *extraTitleMsg)
! {
! if (exceptionHandler)
! exceptionHandler(action, extraTitleMsg, context);
! else
! TRACE("ExceptionHandler: no exception handler available\n");
! }
!
! ExceptionHandlerFunc SetExceptionHandler(ExceptionHandlerFunc handler)
! {
! ExceptionHandlerFunc oldHandler = exceptionHandler;
! exceptionHandler = handler;
! return oldHandler;
}
Index: win32virt.cpp
===================================================================
RCS file: /cvsroot/pywin32/pywin32/Pythonwin/win32virt.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** win32virt.cpp 1 Sep 1999 23:33:03 -0000 1.1
--- win32virt.cpp 7 Oct 2004 08:45:24 -0000 1.2
***************
*** 16,20 ****
//
//////////////////////////////////////////////////////////////////////
- extern BOOL DisplayPythonTraceback(PyObject *exc_type, PyObject *exc_val, PyObject *exc_tb, const char *extraTitleMsg = NULL);
extern BOOL bInFatalShutdown;
--- 16,19 ----
***************
*** 92,97 ****
TRACE("CallVirtual : callback failed with exception\n");
gui_print_error();
PyObject *obRepr = PyObject_Repr(handler);
! char *szRepr = PyString_AsString(obRepr);
wsprintf(msg, "%s() virtual handler (%s) raised an exception", (const char *)csHandlerName, szRepr);
Py_XDECREF(obRepr);
--- 91,99 ----
TRACE("CallVirtual : callback failed with exception\n");
gui_print_error();
+ // this will probably fail if we are already inside the exception handler
PyObject *obRepr = PyObject_Repr(handler);
! char *szRepr = "<no representation (PyObject_Repr failed)>";
! if (obRepr)
! szRepr = PyString_AsString(obRepr);
wsprintf(msg, "%s() virtual handler (%s) raised an exception", (const char *)csHandlerName, szRepr);
Py_XDECREF(obRepr);
***************
*** 108,115 ****
csAddnMsg += " handler";
! PyObject *type, *value, *traceback;
! PyErr_Fetch(&type, &value, &traceback);
! DisplayPythonTraceback(type, value, traceback, csAddnMsg);
! PyErr_Restore(type, value, traceback);
}
return FALSE;
--- 110,114 ----
csAddnMsg += " handler";
! ExceptionHandler(EHA_DISPLAY_DIALOG, NULL, csAddnMsg);
}
return FALSE;
Index: win32thread.cpp
===================================================================
RCS file: /cvsroot/pywin32/pywin32/Pythonwin/win32thread.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** win32thread.cpp 20 Jan 2004 22:28:58 -0000 1.5
--- win32thread.cpp 7 Oct 2004 08:45:24 -0000 1.6
***************
*** 160,165 ****
PyErr_Clear();
else {
! fprintf(stderr, "Unhandled exception in thread:\n");
! PyErr_Print();
}
}
--- 160,164 ----
PyErr_Clear();
else {
! ExceptionHandler(EHA_PRINT_ERROR, "Unhandled exception in thread");
}
}
|