Better exception handling

Hi All,

I love wxPython! One thing that worries me for my end-users is the
inability to see potential errors. When my GUI app is ran from a
console window, the exception is thrown in there. But when somethign
happens and the console window is not there, I would like to see an
error window similar to the stack walker. The way it is now, errors
and exceptions are eaten if I rename my app's extension to myapp.pyw
..

I would not like that as it leads to undesired behaviour and people
not seeing an error and think a particular button does not do anything
can cause more harm then showing an error dialog. Also if there is no
feedback, not many people will file a report.

Is there a way to get errors back from python's exceptions when there
is no console window??

Regards,
- Jorgen

The default behavior is for all output (including uncaught exceptions)
to be show in a popup frame which will be created on demand. You can
configure this in several ways with the argument to your wx.App
constructor. You probably have redirect=False, if it prints to the
command window you were launched in.

···

On 6/28/07, Jorgen Bodde <jorgen.maillist@gmail.com> wrote:

Hi All,

I love wxPython! One thing that worries me for my end-users is the
inability to see potential errors. When my GUI app is ran from a
console window, the exception is thrown in there. But when somethign
happens and the console window is not there, I would like to see an
error window similar to the stack walker. The way it is now, errors
and exceptions are eaten if I rename my app's extension to myapp.pyw
..

I would not like that as it leads to undesired behaviour and people
not seeing an error and think a particular button does not do anything
can cause more harm then showing an error dialog. Also if there is no
feedback, not many people will file a report.

Is there a way to get errors back from python's exceptions when there
is no console window??

Regards,
- Jorgen

Well, I can't speak for everyone, but here's what I do
when developing a wxPython app. Feel free to tell me
if there is a better way:

[1] I write my code in the usual way and keep an eye
out for the obvious places that errors will get thrown
(file errors, communication errors, etc.) and catch
these with try/except statements. I put up Dialogs to
warn users about what is going on.

[2] I debug my code with the console going so I can
see what exceptions get thrown. Then I fix my bugs
and catch any exceptions that I had not originally
planned for.

[3] Once I think my code is pretty stable, I add the
following to my main program:

sys.stderr = open(Const.ErrLog, "w")

That way if there are any errors that dump to stderr,
they will get tossed in a file. When a user calls me
to complain that something is not working right, I
have them replicate the problem and then e-mail me the
log file so I can see the traceback.

I suppose it would be possible to replace a file with
a class that brings up dialog, but before you write
that, I recommend that you:

[1] Keep logging stuff to a file so that when users
call, they don't have to read off lines and lines of
traceback to you.

[2] Remember that stderr text can be generated in
threads other than the main thread, so be sure you
create a custom event to signal the display of an
exception instead of trying to do it in your new
stderr gathering class.

Good luck,
Gre7g

···

--- Jorgen Bodde <jorgen.maillist@gmail.com> wrote:

Hi All,

I love wxPython! One thing that worries me for my
end-users is the
inability to see potential errors. When my GUI app
is ran from a
console window, the exception is thrown in there.
But when somethign
happens and the console window is not there, I would
like to see an
error window similar to the stack walker. The way it
is now, errors
and exceptions are eaten if I rename my app's
extension to myapp.pyw

____________________________________________________________________________________
Don't get soaked. Take a quick peak at the forecast
with the Yahoo! Search weather shortcut.
http://tools.search.yahoo.com/shortcuts/#loc_weather

That's strange, the help file I have for wxWidgets
shows that wx.App's constructor takes no parameters.
I had no idea you could tweak it. Can you point me at
a list of what we can set?

Thanks,
Gre7g

···

--- Chris Mellon <arkanes@gmail.com> wrote:

On 6/28/07, Jorgen Bodde <jorgen.maillist@gmail.com>
The default behavior is for all output (including
uncaught exceptions)
to be show in a popup frame which will be created on
demand. You can
configure this in several ways with the argument to
your wx.App
constructor. You probably have redirect=False, if it
prints to the
command window you were launched in.

____________________________________________________________________________________
Get the Yahoo! toolbar and be alerted to new email wherever you're surfing.
http://new.toolbar.yahoo.com/toolbar/features/mail/index.php

http://wxpython.wxcommunity.com/docs/api/wx.App-class.html#__init__

This is a case where the wxPython API differs from the C++ wxWidgets api.

···

On 6/28/07, Gre7g Luterman <hafeliel@yahoo.com> wrote:

--- Chris Mellon <arkanes@gmail.com> wrote:

> On 6/28/07, Jorgen Bodde <jorgen.maillist@gmail.com>
> The default behavior is for all output (including
> uncaught exceptions)
> to be show in a popup frame which will be created on
> demand. You can
> configure this in several ways with the argument to
> your wx.App
> constructor. You probably have redirect=False, if it
> prints to the
> command window you were launched in.

That's strange, the help file I have for wxWidgets
shows that wx.App's constructor takes no parameters.
I had no idea you could tweak it. Can you point me at
a list of what we can set?

You can write an 'exception hook' function, and assign it to
sys.excepthook . That will allow you to capture only exceptions.

As an alternative:

Step 1:
    a = wx.App(0)

Step 2:
    sys.stdout = sys.stderr = something

Where 'something' is some sort of logging/display class for handling
exceptions/output.

- Josiah

···

"Jorgen Bodde" <jorgen.maillist@gmail.com> wrote:

Hi All,

I love wxPython! One thing that worries me for my end-users is the
inability to see potential errors. When my GUI app is ran from a
console window, the exception is thrown in there. But when somethign
happens and the console window is not there, I would like to see an
error window similar to the stack walker. The way it is now, errors
and exceptions are eaten if I rename my app's extension to myapp.pyw
..

I would not like that as it leads to undesired behaviour and people
not seeing an error and think a particular button does not do anything
can cause more harm then showing an error dialog. Also if there is no
feedback, not many people will file a report.

Is there a way to get errors back from python's exceptions when there
is no console window??

I tried to start my app with redirect = True, but nothing seems to
happen. Can someone show me a mini example where a python exception
gets caught and a window is shown???

What I basically do is create my app with;

import gui.guitarportfolio as gpf

guitarportfolio = gpf.GuitarPortfolioApp(0, True)
guitarportfolio.MainLoop()

And there is no difference when I run this as a .pyw file where there
is no console window,

Regards,
- Jorgen

···

On 6/28/07, Chris Mellon <arkanes@gmail.com> wrote:

On 6/28/07, Gre7g Luterman <hafeliel@yahoo.com> wrote:
> --- Chris Mellon <arkanes@gmail.com> wrote:
>
> > On 6/28/07, Jorgen Bodde <jorgen.maillist@gmail.com>
> > The default behavior is for all output (including
> > uncaught exceptions)
> > to be show in a popup frame which will be created on
> > demand. You can
> > configure this in several ways with the argument to
> > your wx.App
> > constructor. You probably have redirect=False, if it
> > prints to the
> > command window you were launched in.
>
> That's strange, the help file I have for wxWidgets
> shows that wx.App's constructor takes no parameters.
> I had no idea you could tweak it. Can you point me at
> a list of what we can set?

NameBright - Coming Soon

This is a case where the wxPython API differs from the C++ wxWidgets api.

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwidgets.org
For additional commands, e-mail: wxPython-users-help@lists.wxwidgets.org

http://pastie.textmate.org/74448

Gre7g

···

--- Jorgen Bodde <jorgen.maillist@gmail.com> wrote:

I tried to start my app with redirect = True, but
nothing seems to
happen. Can someone show me a mini example where a
python exception
gets caught and a window is shown???

      ____________________________________________________________________________________
Shape Yahoo! in your own image. Join our Network Research Panel today! http://surveylink.yahoo.com/gmrs/yahoo_panel_invite.asp?a=7

Hi Jorgen,

Jorgen Bodde wrote:

Hi All,

I love wxPython! One thing that worries me for my end-users is the
inability to see potential errors. When my GUI app is ran from a
console window, the exception is thrown in there. But when somethign
happens and the console window is not there, I would like to see an
error window similar to the stack walker. The way it is now, errors
and exceptions are eaten if I rename my app's extension to myapp.pyw
..

I would not like that as it leads to undesired behaviour and people
not seeing an error and think a particular button does not do anything
can cause more harm then showing an error dialog. Also if there is no
feedback, not many people will file a report.

Is there a way to get errors back from python's exceptions when there
is no console window??

You already got suggestions from others but here a few more on how you could handle exceptions.

I redirect both stdout and stderr to files, then have an option to log all the SQL command (as my app uses a db) and then define an exception handler which puts a time stamp into the log file and logs the exception and puts up a dialog showing the error log files, catching the version information (OS and my app version) and it has an option for the user to send the errors via SMTP or MAPI to a support e-mail address.

The following are a few code snippets which might be useful.

        self.RedirectLogFiles()
        sys.excepthook = self.MyExceptionHandler

    def RedirectLogFiles(self):
        sp = wx.StandardPaths.Get()
        userdir, userdoc = os.path.split(sp.GetDocumentsDir())
        logFolder = os.path.join(userdir, 'YourAppName')
        if not os.path.exists(logFolder):
            os.mkdir(logFolder)
               sqllogFile = os.path.join(logFolder, 'sqllog.txt')
        stdoutFile = os.path.join(logFolder, 'stdoutlog.txt')
        stderrFile = os.path.join(logFolder, 'stderrlog.txt')

        self.sqllog = file(sqllogFile, 'a+')
        self.stdoutlog = file(stdoutFile, 'a+')
        self.stderrlog = file(stderrFile, 'a+')

        sys.stdout = self.stdoutlog
        sys.stderr = self.stderrlog

    def MyExceptionHandler(self, type, value, trace_back):
        """Catch exceptions, log them to file and show error dialog
        """ timestamp = myTime.asctime(myTime.localtime(myTime.time()))
        self.stdoutlog.write('**** %s ****\n' % timestamp)
        traceback.print_exception(type, value, trace_back, file=self.stdoutlog)
        self.stdoutlog.write('\n')
        # to ensure that errorDialog is shown immediatly
        self.stdoutlog.flush()
               self.ReportException(msg=2)

Best regards
Werner

Thank you for your example, but nothing seems to happen.

When I run this in a console I get:

jorg@shale:~/personal/src/GuitarPortfolio/tmp$ python fire.pyw
Traceback (most recent call last):
  File "fire.pyw", line 15, in OnErr
    1/0
ZeroDivisionError: integer division or modulo by zero
Traceback (most recent call last):
  File "fire.pyw", line 15, in OnErr
    1/0

When I run this in a shorcut named fire.pyw I see the app, I click the
button and nothing happens. The exception gets absorbed.

I'm using wxPython 2.8.4 on wxGTK (Ubuntu Feisty)

Any ideas what might be wrong? With regards,
- Jorgen

···

On 6/28/07, Gre7g Luterman <hafeliel@yahoo.com> wrote:

--- Jorgen Bodde <jorgen.maillist@gmail.com> wrote:

> I tried to start my app with redirect = True, but
> nothing seems to
> happen. Can someone show me a mini example where a
> python exception
> gets caught and a window is shown???

http://pastie.textmate.org/74448

Gre7g

      ____________________________________________________________________________________
Shape Yahoo! in your own image. Join our Network Research Panel today! http://surveylink.yahoo.com/gmrs/yahoo_panel_invite.asp?a=7

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwidgets.org
For additional commands, e-mail: wxPython-users-help@lists.wxwidgets.org

I'll have to defer to the GTK users. It works fine
under Windows XP.

Gre7g

____________________________________________________________________________________Ready for the edge of your seat?
Check out tonight's top picks on Yahoo! TV.

···

--- Jorgen Bodde <jorgen.maillist@gmail.com> wrote:

Thank you for your example, but nothing seems to
happen.

When I run this in a console I get:

jorg@shale:~/personal/src/GuitarPortfolio/tmp$
python fire.pyw
Traceback (most recent call last):
  File "fire.pyw", line 15, in OnErr
    1/0
ZeroDivisionError: integer division or modulo by
zero
Traceback (most recent call last):
  File "fire.pyw", line 15, in OnErr
    1/0

When I run this in a shorcut named fire.pyw I see
the app, I click the
button and nothing happens. The exception gets
absorbed.

I'm using wxPython 2.8.4 on wxGTK (Ubuntu Feisty)

Chris Mellon wrote:

···

On 6/28/07, Jorgen Bodde <jorgen.maillist@gmail.com> wrote:

Hi All,

I love wxPython! One thing that worries me for my end-users is the
inability to see potential errors. When my GUI app is ran from a
console window, the exception is thrown in there. But when somethign
happens and the console window is not there, I would like to see an
error window similar to the stack walker. The way it is now, errors
and exceptions are eaten if I rename my app's extension to myapp.pyw
..

I would not like that as it leads to undesired behaviour and people
not seeing an error and think a particular button does not do anything
can cause more harm then showing an error dialog. Also if there is no
feedback, not many people will file a report.

Is there a way to get errors back from python's exceptions when there
is no console window??

Regards,
- Jorgen

The default behavior is for all output (including uncaught exceptions)
to be show in a popup frame which will be created on demand. You can
configure this in several ways with the argument to your wx.App
constructor. You probably have redirect=False, if it prints to the
command window you were launched in.

Also, you can change the class used for creating the output window to some class that you write by setting wx.App.outputWindowClass. For example Chandler uses this to put the error output in a window that can be used for emailing the error text and other info to QA.

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Jorgen Bodde wrote:

Thank you for your example, but nothing seems to happen.

When I run this in a console I get:

jorg@shale:~/personal/src/GuitarPortfolio/tmp$ python fire.pyw
Traceback (most recent call last):
File "fire.pyw", line 15, in OnErr
   1/0
ZeroDivisionError: integer division or modulo by zero
Traceback (most recent call last):
File "fire.pyw", line 15, in OnErr
   1/0

When I run this in a shorcut named fire.pyw I see the app, I click the
button and nothing happens. The exception gets absorbed.

I'm using wxPython 2.8.4 on wxGTK (Ubuntu Feisty)

Any ideas what might be wrong? With regards,

The default on wxGTK is to not redirect. Just change it to

App = TestApp(redirect=True)

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

You could download and run GNUmed and click on the "test
error handling" menu item :slight_smile:

On Debian you can do

  apt-get install -t testing gnumed-client

Else you can download a tarball from

  Index of /downloads/client/0.2

Version 0.2.6.3 is the latest. The login offers the option
to connect to a public server on the internet, use
any-doc/any-doc for login/password.

Karsten

···

On Thu, Jun 28, 2007 at 06:28:22PM +0200, Jorgen Bodde wrote:

Subject: Re: [wxPython-users] Better exception handling

I tried to start my app with redirect = True, but nothing seems to
happen. Can someone show me a mini example where a python exception
gets caught and a window is shown???

--
GPG key ID E4071346 @ wwwkeys.pgp.net
E167 67FD A291 2BEA 73BD 4537 78B9 A9F9 E407 1346

Robin, as you can see in my example I did that. I could not get any
redirection. Also if I try the example given on Windows (by Gre7g), it
works. I do get a window upon an error. I added the redirect = True
and tried;

···

------------------

import wx

class TestApp(wx.App):
    def OnInit(self):
        self.MainFrame = wx.Frame(None, -1, "Test Frame")
        self.MainFrame.SetBackgroundColour(wx.WHITE)
        wx.StaticText(self.MainFrame, -1, "Click me!", wx.Point(50, 30))
        self.ErrButton = wx.Button(self.MainFrame, -1, "Error",
wx.Point(50, 50))
        self.ErrButton.Bind(wx.EVT_BUTTON, self.OnErr)
        self.MainFrame.Show()
        return True
    def OnErr(self, Event):
        1/0

App = TestApp(0, redirect = True)
App.MainLoop()

--------------

And I get the error:

Traceback (most recent call last):
  File "test.py", line 15, in <module>
    App = TestApp(0, redirect = True)
TypeError: __init__() got multiple values for keyword argument 'redirect'

So I just add 0, True instead of the keyword, and still no luck. I get
again in the console window:

jorg@shale:~/Desktop$ python test.py
Traceback (most recent call last):
  File "test.py", line 13, in OnErr
    1/0
ZeroDivisionError: integer division or modulo by zero

----------

What do I need to do more to get the redirect window on wxGTK, Ubuntu Feisty?
Can someone comfirm the above test app that it shows a redirect
window? It does not work for me..

Regards,
- Jorgen

redirect is the first parameter, so you're specifying
it twice. Try:

App = TestApp(True)

or:

App = TestApp(redirect=True)

Gre7g

···

--- Jorgen Bodde <jorgen.maillist@gmail.com> wrote:

App = TestApp(0, redirect = True)

____________________________________________________________________________________
Sucker-punch spam with award-winning protection.
Try the free Yahoo! Mail Beta.
http://advision.webevents.yahoo.com/mailbeta/features_spam.html

Hi Gre7g,

YES!!! That was it! Stupid me I thought the first parameter in my
App() class was the parent specification or something. I never knew
how I actually got that 0 there :frowning: But it works! Thanks a lot for all
your help (you and the others)

I'm still a wxPython newbie, so I'm thankful for all the patience :wink:

It's really important that people who use my app get feedback on
exceptions which they can email me quickly, and a redirect box is
exactly what I need.

Thanks!
- Jorgen

···

On 6/29/07, Gre7g Luterman <hafeliel@yahoo.com> wrote:

--- Jorgen Bodde <jorgen.maillist@gmail.com> wrote:

> App = TestApp(0, redirect = True)

redirect is the first parameter, so you're specifying
it twice. Try:

App = TestApp(True)

or:

App = TestApp(redirect=True)

Gre7g

____________________________________________________________________________________
Sucker-punch spam with award-winning protection.
Try the free Yahoo! Mail Beta.
http://advision.webevents.yahoo.com/mailbeta/features_spam.html

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwidgets.org
For additional commands, e-mail: wxPython-users-help@lists.wxwidgets.org

Hi Jorgen,

Jorgen Bodde wrote:

Hi All,

I love wxPython! One thing that worries me for my end-users is the
inability to see potential errors. When my GUI app is ran from a
console window, the exception is thrown in there. But when somethign
happens and the console window is not there, I would like to see an
error window similar to the stack walker. The way it is now, errors
and exceptions are eaten if I rename my app's extension to myapp.pyw
..

I would not like that as it leads to undesired behaviour and people
not seeing an error and think a particular button does not do anything
can cause more harm then showing an error dialog. Also if there is no
feedback, not many people will file a report.

Is there a way to get errors back from python's exceptions when there
is no console window??

Regards,
- Jorgen

Here is a simple pattern I use for gui apps with wxPython/excepthook:

import sys, traceback, wx

def excepthook(type, value, trace):
     if wx and sys and traceback:
         exc = traceback.format_exception(type, value, trace)
         for e in exc: wx.LogError(e)
         wx.LogError('Unhandled Error: %s: %s'%(str(type), str(value)))
         sys.__excepthook__(type, value, trace)

And in your initialization code:
     sys.excepthook = excepthook

Hi Riaan,

Awesome! I added this to my main code in the .pyw variant of my app,
and it works as a charm!

Thanks!
- Jorgen

···

On 6/30/07, Riaan Booysen <riaan@e.co.za> wrote:

Hi Jorgen,

Jorgen Bodde wrote:
> Hi All,
>
> I love wxPython! One thing that worries me for my end-users is the
> inability to see potential errors. When my GUI app is ran from a
> console window, the exception is thrown in there. But when somethign
> happens and the console window is not there, I would like to see an
> error window similar to the stack walker. The way it is now, errors
> and exceptions are eaten if I rename my app's extension to myapp.pyw
> ..
>
> I would not like that as it leads to undesired behaviour and people
> not seeing an error and think a particular button does not do anything
> can cause more harm then showing an error dialog. Also if there is no
> feedback, not many people will file a report.
>
> Is there a way to get errors back from python's exceptions when there
> is no console window??
>
> Regards,
> - Jorgen

Here is a simple pattern I use for gui apps with wxPython/excepthook:

import sys, traceback, wx

def excepthook(type, value, trace):
     if wx and sys and traceback:
         exc = traceback.format_exception(type, value, trace)
         for e in exc: wx.LogError(e)
         wx.LogError('Unhandled Error: %s: %s'%(str(type), str(value)))
         sys.__excepthook__(type, value, trace)

And in your initialization code:
     sys.excepthook = excepthook

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwidgets.org
For additional commands, e-mail: wxPython-users-help@lists.wxwidgets.org

Thanks, I will be needing this for future reference. I took Riaans
solution now but I might want logfile I/O as well.

Regards,
- Jorgen

···

On 7/4/07, Werner F. Bruhin <werner.bruhin@free.fr> wrote:

Tal Einat wrote:
> On 6/28/07, *Werner F. Bruhin* <werner.bruhin@free.fr > > <mailto:werner.bruhin@free.fr>> wrote:
>
> I redirect both stdout and stderr to files, then have an option to log
> all the SQL command (as my app uses a db) and then define an
> exception
> handler which puts a time stamp into the log file and logs the
> exception
> and puts up a dialog showing the error log files, catching the version
> information (OS and my app version) and it has an option for the
> user to
> send the errors via SMTP or MAPI to a support e-mail address.
>
> Your error reporting mecanism seems like it could be useful for a lot
> of application developers... any chance of releasing the code for the
> community?
I created a wiki for it.

CustomExceptionHandling - wxPyWiki

Anyone please feel free to add alternative solutions, to correct/enhance
what I put on there.

Werner

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwidgets.org
For additional commands, e-mail: wxPython-users-help@lists.wxwidgets.org