views:

538

answers:

4

I have complex GUI application written in Python and wxPython.

I want it to be certified for Windows Vista, so it has to crash in a way that causes Windows Error Reporting dialog (The one that asks "Do you want to send report to Microsoft?") to appear. This is relevant to test case no 32 from "Certified for Windows Vista Test Cases" document.

Unfortunately when I crash my app with ThreadHijacker tool wxPython shows message like:

Unhandled exception
---------------------------
An unhandled exception occurred. Press "Abort" to terminate the program,
"Retry" to exit the program normally and "Ignore" to try to continue.
---------------------------
Abort   Retry   Ignore

How can I prevent wxPython from showing this message? I have custom sys.excepthook, but it seems that this dialog is shown before my except hook can interfere.

EDIT:

wxWidgets docs says that wxAppConsole::OnExceptionInMainLoop is called and under MSW it displays some fancy dialog that allows user to choose between the different options. It seems however, that wxPython doesn't allow overloading that function... Does anyone know how to change default behaviour of wxAppConsole::OnExceptionInMainLoop in wxPython?
I prefer solutions that are on Python level over those that go into C/C++

EDIT2:

All in all, I asked at wxPython mailing list, and Robin Dunn answered that he'll look into making wxAppConsole::OnExceptionInMainLoop overridable in next releases of wxPython. Since I couldn't wait, I had to compile my own version of wxPython which does not include that function. It turned out that the presence of wxAppConsole::OnExceptionInMainLoop function can be enabled/disabled by proper setting of compilation flags.

+1  A: 

If I remember correctly, this is a catch(...) at top level (wxApp) in wxWidgets. You can either use a vectored Exception Handler or _set_se_translator() to get a first shot at the Structured Exception, and exit to WER, i.e. ReportFault() from there.

MSalters
You're right about wxWidgets and ReportFault(), this pointed me in correct direction. But in wxPython I can not change default behaviour (it seems it's not exported to Python).
Abgan
Might want to update your question, seems you want a 100% python solution. Both solutions I suggested assume native ccode, either at the underlying CRT or at Win32 level.
MSalters
+1  A: 

Is it possible for you to just handle everything? You would have to, I guess, put a try:except: block around every method bound to a widget. You could write a decorator:

def catch_exception(f):
    def safe(*args, **kw):
        try:
            f(*args, **kw)
        except Exception, e:
            handle_exception(e)
    return safe

def handle_exception(e):
    # do Vista stuff
    sys.exit()

Then decorate any function that could be called by the mainloop (since I presume that's where wxPython does its own catching).

John Fouhy
My code has >80k lines of code, so that would take quite a lot of time... I'm afraid that error is raised in C++ code, and is fully handled in C++ level. What I really want to do is to handle that error *BEFORE* wxWidgets will do so.
Abgan
Anyway - I'm going to check your method, as it didn't cross my mind. Thank you and upvote for you. :-)
Abgan
+1  A: 

It all ended up with compiling my own wxWidgets and wxPython, with just one compilation flag changed: wxUSE_EXCEPTIONS should be set to 0.

Robin Dunn wrote that he will try to patch wxPython, so this behaviour could be modified without recompiling of the whole library.

Abgan