Scanning a file

Alex Martelli aleaxit at yahoo.com
Sun Oct 30 19:08:05 EST 2005


Steven D'Aprano <steve at REMOVETHIScyber.com.au> wrote:
   ...
> > No.  But if you get a totally unexpected exception, 
> 
> I'm more concerned about getting an expected exception -- or more
> accurately, *missing* an expected exception. Matching on Exception is too
> high. EOFError will probably need to be handled separately, since it often
> isn't an error at all, just a change of state. IOError is the bad one.
> What else can go wrong?

Lots of things, but not ones you should WISH your application to
survive.

> > something that shows
> > the world has gone crazy and most likely any further action you perform
> > would run the risk of damaging the user's persistent data since the
> > macchine appears to be careening wildly out of control... WHY would you
> > want to perform any further action?
> 
> In circumstances where, as you put it, the hard disk has crashed, the CPU
> is on strike, or the memory has melted down, not only can you not recover
> gracefully, but you probably can't even fail gracefully -- at least not
> without a special purpose fail-safe operating system.

Right: as I explained, all you can do is switch operation over to a "hot
spare" server (a different machine), through the good services of a
"monitor" machine - and hope the redundancy you've built into your
storage system (presumably a database with good solid mirroring running
on other machines yet, if your app is as critical as that) has survived.


> I'm not concerned with mylist.append(None) unexpectedly -- and
> impossibly? -- raising an ImportError. I can't predict every way things
> can explode, and even if they do, I can't safely recover from them. But I

Exactly my point -- and yet if you use "except:", that's exactly what
you're TRYING to do, rather than let your app die.

> can fail gracefully from *expected* errors: rather than the application
> just crashing, I can at least try to put up a somewhat informative dialog
> box, or at least print something to the console.

You can do that from your sys.excepthook routine, if it's OK for your
app to die afterwards.  What we're discussing here are only, and
strictly, cases in which you wish your app to NOT die, but rather keep
processing (not just give nice error diagnostics and then terminate,
that's what sys.excepthook is for).  And what I'm saying is that you
should keep processing only for errors you *DO* expect, and should not
even try if the error is NOT expected.

>. If opening a preferences
> file fails, I can fall back on default settings. If writing the
> preferences file fails, I can tell the user that their settings won't be
> saved, and continue. Just because the disk is full or their disk quota is
> exceeded, doesn't necessarily mean the app can't continue with the job on
> hand.

Sure, that's why you catch IOError, which covers these _expected_ cases
(or, if you want to be a bit wider, maybe OSError) AND check its errno
attribute to ensure you haven't mistakenly caught something you did NOT
in fact expect (and thus can't really handle), to use a bare raise
statement to re-raise the "accidentally caught" exception if needed.

But if something goes wrong that you had NOT anticipated, just log as
much info as you can for the postmortem, give nice diagnostics to the
user if you wish, and do NOT keep processing -- and for these
diagnostic-only purposes, use sys.excepthook, not a slew of try/except
all over your application making it crufty and unmaintainable.


Alex



More information about the Python-list mailing list