Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #44652 > unrolled thread

question about try/except blocks

Started byJ <dreadpiratejeff@gmail.com>
First post2013-05-02 21:54 -0400
Last post2013-05-03 03:02 +0000
Articles 2 — 2 participants

Back to article view | Back to comp.lang.python


Contents

  question about try/except blocks J <dreadpiratejeff@gmail.com> - 2013-05-02 21:54 -0400
    Re: question about try/except blocks Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-05-03 03:02 +0000

#44652 — question about try/except blocks

FromJ <dreadpiratejeff@gmail.com>
Date2013-05-02 21:54 -0400
Subjectquestion about try/except blocks
Message-ID<mailman.1259.1367546098.3114.python-list@python.org>
I have this function in a class:

 def write_file(self, data, dest):
        with open(dest, 'wb', 0) as outfile:
            try:
                print("IN WRITE_FILE")
                outfile.write(self.data)
            except IOError as exc:
                logging.error("Unable to write data to %s: %s", dest, exc)
                return False
            else:
                outfile.flush()
                os.fsync(outfile.fileno())
                return True


Which is simply called like this:
test.write_file(test.data, target_file)

However, when this is called on a read-only filesystem, it throws an OSError:

  File "./scripts/removable_storage_test", line 118, in write_file
    with open(dest, 'wb', 0) as outfile:
OSError: [Errno 30] Read-only file system:
'/media/bladernr/5747-AD2E/tmpfbzsxk.0'

So what I am not sure of is how to handle this?

Would it be better to wrap the call and catch the OSError there, or
wrap the whole with open() block in the function itself?

My thought is to wrap the with open() call in the function so that I'm
not wrapping the function call every time I use the class somewhere,
but then I am not sure of that as it leads to nested try blocks like
so:

try:
    with open(dest, 'wb', 0) as outfile:
        try:
            stuff
        except IOError as exec:
            more stuff
        else:
            other stuff
except OSError as exc:
     error handling stuff
     return False


I think, functionally, that should work, but should nested try/except
blocks be avoided?

[toc] | [next] | [standalone]


#44654

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-05-03 03:02 +0000
Message-ID<518328ca$0$29997$c3e8da3$5496439d@news.astraweb.com>
In reply to#44652
On Thu, 02 May 2013 21:54:29 -0400, J wrote:

> I have this function in a class:
> 
>  def write_file(self, data, dest):
>         with open(dest, 'wb', 0) as outfile:
>             try:
>                 print("IN WRITE_FILE")
>                 outfile.write(self.data)
>             except IOError as exc:
>                 logging.error("Unable to write data to %s: %s", dest,
>                 exc) return False
>             else:
>                 outfile.flush()
>                 os.fsync(outfile.fileno())
>                 return True
[...]
> I think, functionally, that should work, but should nested try/except
> blocks be avoided?


Not particularly. Try/except is cheap to set up, nesting them doesn't 
cost much.

But having said that, your code as given does not protect against rare
but possible errors. For example, just because you can open the file for 
writing doesn't mean you can write to it; just because you can write to 
it doesn't mean flush will succeed; just because flush succeeds doesn't 
mean that syncing to disk will succeed. Any IO operation might fail. 
While you can wrap each one individually, it's probably better to wrap 
the whole lot at once. I'd write it like this:


def write_file(self, data, dest):
    try:
        with open(dest, 'wb', 0) as outfile:
            print("IN WRITE_FILE")
            outfile.write(self.data)
            outfile.flush()
            os.fsync(outfile.fileno())
    except (OSError, IOError) as exc:
        logging.error("Error writing data to %s: %s", dest, exc)
        return False
    return True



File IO is one of the rare exceptions to the idea that try/except blocks 
should wrap the least amount of code possible.



-- 
Steven

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web