switching to PS/SVG backends

I've noticed a problem as follows:

You run a GUI backend (GTK, GTKAgg etc) and want to save a figure.
You select the toolbar save button and type in a .ps or .svg filename
and select save.
The GUI backend switches to the PS/SVG backend to save the file.
If there is a problem saving the file, for example you do not have write
permission to the directory, PS/SVG backends will kill your GUI
application with sys.exit()

I don't think failure to save a file should be a fatal error.
Perhaps PS/SVG print_figure() could raise an exception for the GUI
backend to catch so it can popup an error message and continue.

Steve

Hello Steve,

I don't think failure to save a file should be a fatal error.
Perhaps PS/SVG print_figure() could raise an exception for the GUI
backend to catch so it can popup an error message and continue.

Even now you can probably (not tried) catch the SystemExit
exception and prevent the program from aborting.
Do you think raising SystemExit like

    raise SystemExit("error while writing file: permission denied")

would be good enough. The GUI frontend could catch SystemExit,
check whether the associated value is a string, and then display
this string in an error message box.

What do you think?

Jochen

···

On Wed, Nov 17, 2004 at 11:00:32PM +0800, Steve Chaplin wrote:
--

Jochen Voss schrieb:

Hello Steve,

I don't think failure to save a file should be a fatal error.
Perhaps PS/SVG print_figure() could raise an exception for the GUI
backend to catch so it can popup an error message and continue.

Even now you can probably (not tried) catch the SystemExit
exception and prevent the program from aborting.
Do you think raising SystemExit like

    raise SystemExit("error while writing file: permission denied")

would be good enough. The GUI frontend could catch SystemExit,
check whether the associated value is a string, and then display
this string in an error message box.

What do you think?

Bad design. Doing exception analysis based on string matching for the message is very brittle. A single change in capitalization of the message can break things down the road.

It's _far_ better to either:

1. have the ps/svg backends do whatever cleanup they want, and then reraise the original exception unchanged

2. or simply make a matplotlib.SaveError exception which can be explicitly caught based on class matching, which is the preferred python way of doing this.

Best,

f

···

On Wed, Nov 17, 2004 at 11:00:32PM +0800, Steve Chaplin wrote:

Hello,

Bad design. Doing exception analysis based on string matching for the
message is very brittle. A single change in capitalization of the message
can break things down the road.

Sorry, maybe I was not clear enough.
What I tried to suggest was:

1) GUI backends should catch the SystemExit exception from the PS backend,
  thus being able to continue running even if the backend aborts with an
  error.

2) GUI backends should in case that they caught a SystemExit exception
  notify the user that saving the figure as PostScript failed. If
  the exception is associated with an error message string, they could
  display this string to the user.

1. have the ps/svg backends do whatever cleanup they want, and then reraise
the original exception unchanged

2. or simply make a matplotlib.SaveError exception which can be explicitly
caught based on class matching, which is the preferred python way of doing
this.

Maybe. But how is any information except "the backend failed with
error message ..." useful to the GUI? Would it act differently on
an font-not-found condition then it would on a save-failed one?

All the best,
Jochen

···

On Wed, Nov 17, 2004 at 10:54:49AM -0700, Fernando Perez wrote:
--

At the moment the PS backend does
  try:
      fh = file(outfile, 'w')
  except IOError:
      error_msg_ps('Could not open %s for writing' % outfile)

which translates into
  try:
      fh = file(outfile, 'w')
  except IOError:
      verbose.report_error('Error: Could not open %s for writing' %
outfile)
      sys.exit()

The backend does not do any cleanup after the exception, so I think it
could be changed to just
      fh = file(outfile, 'w')
allowing the exception terminate the program with the error message
appearing at the end of the traceback.

Then the GUI backends can then do
    from backend_svg import FigureCanvasSVG as FigureCanvas
    try:
        fc = self.switch_backends(FigureCanvas)
        fc.print_figure(filename, dpi, facecolor, edgecolor,
orientation)
    except IOError, exc:
        error_msg("%s: %s" % (exc.filename, exc.strerror), parent=self)

I tried this calling the SVG backend directly and by switching to the
SVG backend from the GTK backend and it works OK.

Steve

···

On Wed, 2004-11-17 at 10:54 -0700, Fernando Perez wrote:

Jochen Voss schrieb:
> Hello Steve,
>
> On Wed, Nov 17, 2004 at 11:00:32PM +0800, Steve Chaplin wrote:
>
>>I don't think failure to save a file should be a fatal error.
>>Perhaps PS/SVG print_figure() could raise an exception for the GUI
>>backend to catch so it can popup an error message and continue.
>
> Even now you can probably (not tried) catch the SystemExit
> exception and prevent the program from aborting.
> Do you think raising SystemExit like
>
> raise SystemExit("error while writing file: permission denied")
>
> would be good enough. The GUI frontend could catch SystemExit,
> check whether the associated value is a string, and then display
> this string in an error message box.
>
> What do you think?

Bad design. Doing exception analysis based on string matching for the message
is very brittle. A single change in capitalization of the message can break
things down the road.

It's _far_ better to either:

1. have the ps/svg backends do whatever cleanup they want, and then reraise
the original exception unchanged

2. or simply make a matplotlib.SaveError exception which can be explicitly
caught based on class matching, which is the preferred python way of doing this.

Best,

f

Hello Steve,

At the moment the PS backend does
  try:
      fh = file(outfile, 'w')
  except IOError:
      error_msg_ps('Could not open %s for writing' % outfile)

which translates into
  try:
      fh = file(outfile, 'w')
  except IOError:
      verbose.report_error('Error: Could not open %s for writing' %
outfile)
      sys.exit()

The backend does not do any cleanup after the exception, so I think it
could be changed to just
      fh = file(outfile, 'w')

As I understood John, the plan is to report error messages via the
verbose.report_error function. Where would this be called with
the modified code (especially when there is no GUI backend active)?

allowing the exception terminate the program with the error message
appearing at the end of the traceback.

This looks really ugly to me. But maybe it is the script author's
responsibility to catch this if he cares about this.

Then the GUI backends can then do
    from backend_svg import FigureCanvasSVG as FigureCanvas
    try:
        fc = self.switch_backends(FigureCanvas)
        fc.print_figure(filename, dpi, facecolor, edgecolor,
orientation)
    except IOError, exc:
        error_msg("%s: %s" % (exc.filename, exc.strerror), parent=self)

What about other exceptions thrown by the backend?

I see that passing the original exception to the caller is cleaner
and I would be happy to change the PostScript backend to do this.
The only question for me is: how and when is the "report_error" function
to be used?

All the best,
Jochen

···

On Thu, Nov 18, 2004 at 11:38:10PM +0800, Steve Chaplin wrote:
--