propagation of error messages in matplotlib

At the moment we have error_msg(), the Verbose class and

    > exceptions all working in the same area and a bit of
    > confusion as to which one does what. I don't think we need
    > all three.

    > I suggest - using exceptions to handle errors that may
    > terminate the program, and allowing the matlab interface,
    > GUI backends and user scripts to catch these exceptions. -
    > using verbose for all reporting - merging error_msg() into
    > the Verbose class (with the GUI backends possibly
    > subclassing Verbose to provide a popup error dialog)

I think you are right that the plethora of error reporting strategies
is causing confusion, especially for me! I like the idea of the GUI
backends overriding placing a hook into the python exception handling
process. One possibility would be to do away with
verbose.report_error and error_msg. The GUIs hook into the exception
message, and anywhere we want to report an error we raise a python
exception. And we continue to use verbose.report as before.

I just checked backend_ps and the only place is uses error_msg is

    error_msg_ps('Could not open %s for writing' % outfile)

which would be more naturally handled as an exception anyway.

Steve, could you look into hooking a GTK dialog into the python
exception reporting mechanism to see if this is viable? In summary,
the thought is

  * use verbose only for non-error reporting

  * use exceptions for all error reporting

  * work some GUI magic to transparently get the errors forwarded to a
    dialog box w/o using special functions

As for verbose.report, I'm not convinced it is a good idea to hook
this into the GUI. For one thing, some reporting occurs before the
backend is determined. For another, it would also require some
caching of messages because if 30 messages generate 30 popups it will
get annoying quick. These things are manageable, but I think the main
use for verbose.report is debugging a problem, in which case simply
having the messages go to a stdout or a file may be the best place for
them.

JDH

Hello,

In summary, the thought is

  * use verbose only for non-error reporting

  * use exceptions for all error reporting

I agree with this.

  * work some GUI magic to transparently get the errors forwarded to a
    dialog box w/o using special functions

Here I have no opinion until I understand the special kind
of magic which is going to be used here.

For another, it would also require some
caching of messages because if 30 messages generate 30 popups it will
get annoying quick.

Yes, we have to be careful here.

As nobody objected to this part of the plan, I changed the PostScript
backend in CVS as follows:

    diff -u -r1.13 backend_ps.py
    --- backend_ps.py 13 Nov 2004 11:41:54 -0000 1.13
    +++ backend_ps.py 19 Nov 2004 16:23:13 -0000
    @@ -529,10 +529,7 @@
     basename, ext = os.path.splitext(outfile)
     if not ext: outfile += '.ps'
     isEPSF = ext.lower().startswith('.ep')
    - try:
    - fh = file(outfile, 'w')
    - except IOError:
    - error_msg_ps('Could not open %s for writing' % outfile)
    + fh = file(outfile, 'w')
     needsClose = True
     title = outfile

Slight problem: it might now be a little bit more difficult to include
the name of the file which could not be opened in the error message.
The IOError exception will probably only have "permission denied" associated
with it.

All the best,
Jochen

···

On Fri, Nov 19, 2004 at 09:23:36AM -0600, John Hunter wrote:
--

I was thinking of something like:

class VerboseGTK(Verbose):
    def report_error(self, s):
        dialog = gtk.MessageDialog(
            parent = None,
            type = gtk.MESSAGE_ERROR,
            buttons = gtk.BUTTONS_OK,
            message_format = msg)
        dialog.run()
        dialog.destroy()

So that the matlab interface can call verbose.report_error() and for
image backends it writes to stdout and for GUI backends it pops up
a message dialog.

You can hook a GTK dialog into unhandled Python exceptions with:
import sys

def exception_handler(type, value, tb):
    """Handle uncaught exceptions"""
    error_msg_gtk(value)

sys.excepthook = exception_handler

(I've added this to backend_gtk.py in cvs if you want to try it out)

But you still need to decide how to handle the exceptions - with some
you need to terminate the program, with others its safe to continue. It
may mean you end up writing a complicated generic exception handler that
tries to handle every possible exception. In that case handling
exceptions individually, the usual way might be better, possibly using
the sys.excepthook to handle the remaining uncaught exceptions, or using
it when you want to terminate the program and want to popup a message
saying "Fatal error..."

Steve

···

On Fri, 2004-11-19 at 09:23 -0600, John Hunter wrote:

I think you are right that the plethora of error reporting strategies
is causing confusion, especially for me! I like the idea of the GUI
backends overriding placing a hook into the python exception handling
process. One possibility would be to do away with
verbose.report_error and error_msg. The GUIs hook into the exception
message, and anywhere we want to report an error we raise a python
exception. And we continue to use verbose.report as before.

I just checked backend_ps and the only place is uses error_msg is

    error_msg_ps('Could not open %s for writing' % outfile)

which would be more naturally handled as an exception anyway.

Steve, could you look into hooking a GTK dialog into the python
exception reporting mechanism to see if this is viable? In summary,
the thought is

  * use verbose only for non-error reporting

  * use exceptions for all error reporting

  * work some GUI magic to transparently get the errors forwarded to a
    dialog box w/o using special functions

As for verbose.report, I'm not convinced it is a good idea to hook
this into the GUI. For one thing, some reporting occurs before the
backend is determined. For another, it would also require some
caching of messages because if 30 messages generate 30 popups it will
get annoying quick. These things are manageable, but I think the main
use for verbose.report is debugging a problem, in which case simply
having the messages go to a stdout or a file may be the best place for
them.

JDH

Hello,

I was thinking of something like:

class VerboseGTK(Verbose):
    def report_error(self, s):
        dialog = gtk.MessageDialog(
            parent = None,
            type = gtk.MESSAGE_ERROR,
            buttons = gtk.BUTTONS_OK,
            message_format = msg)
        dialog.run()
        dialog.destroy()

Alternatively we could make report_error a figure_manager method.
If could default to

class FigureManagerBase:
    def report_error(self, s):
  sys.stderr.write("error: %s\n"%s)

And FigureManagerGTK could overload it with the above code to generate
an error box.

Reasons why I would prefer this:

1) I do not like these global variables which are set on module import
  at all. Using the VerboseGTK idea we would get another instance of this,
  namely something like "currentVerboseClass=VerboseBackend" or such.

  We already have something like this for figure managers, so no new instance
  of this would be created with my suggestion.

  Reporting errors would then work like this:

      manager = get_current_fig_manager()
      manager.canvas.report_error(message)

  which could be wrapped into a function.

2) The main functionality of the Verbose class seems to be,
  that the user can select how many messages he wants to see.
  Error messages (at least fatal ones) should be presented to
  the user in any case, so for me reporting errors does not
  look like an application of the Verbose class.

What do you think?

Jochen

···

On Sat, Nov 20, 2004 at 11:53:01AM +0800, Steve Chaplin wrote:
--