Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catch Broken Pipe in Python 2 AND Python 3

I try to write some code to catch a Broken Pipe Error. The code should run in Python 2.x and Python 3.x.

In Python 2.x a broken pipe is represented by a socket.error

socket.error: [Errno 32] Broken pipe

This was changed in Python 3.x - a broken pipe now is a BrokenPipeError

BrokenPipeError: [Errno 32] Broken pipe

Also the syntax of exception handling has changed a bit (see https://stackoverflow.com/a/34463112/263589) so what I need to do would be something like:

try:
    do_something()
except BrokenPipeError as e: # implies Python 3.x
    resolve_for_python2()
except socket.error as e:
    if sys.version_info[0] == 2: # this is necessary, as in Python >=3.3
                                 # socket.error is an alias of OSError
                                 # https://docs.python.org/3/library/socket.html#socket.error
        resolve_for_python3()
    else:
        raise

There's (at least) one remaining problem: In Python 2.x there is no BrokenPipeError, so whenever there is an exception in do_something() Python 2.x would throw another exception and complain that it doesn't know BrokenPipeError. As socket.error is deprecated in Python 3.x a similar problem could arise in Python 3.x in the near future.

What can I do to make this code run in Python 2.x and Python 3.x?

like image 999
speendo Avatar asked Jan 11 '16 09:01

speendo


People also ask

How does Python handle broken pipe error?

Properly catching IOError to avoid Broken pipe error As a Broken pipe error is an IOError error, we can place a try/catch block in order to catch it, as shown in the following snippet of code: Syntax: import sys, errno.

How do you stop a broken pipe in Python?

Avoid [Errno 32] Broken pipe by ignoring SIGPIPE Do not set SIGPIPE 's disposition to SIG_DFL in order to avoid BrokenPipeError . Doing that would cause your program to exit unexpectedly also whenever any socket connection is interrupted while your program is still writing to it.

What is broken pipe Python?

A "Broken Pipe" error occurs when you try to write to a pipe that has been closed on the other end. Since the code you've shown doesn't involve any pipes directly, I suspect you're doing something outside of Python to redirect the standard output of the Python interpreter to somewhere else.

What is BrokenPipeError Errno 32 broken pipe?

Python interpreter is not capable enough to ignore SIGPIPE by default, instead, it converts this signal into an exception and raises an error which is known as IOError(INPUT/OUTPUT error) also know as 'Error 32' or Broken Pipe Error.


1 Answers

If all you care about are broken pipe errors, then you might want to catch socket.error and simply check whether it's indeed a broken pipe error.

You can do so using the exception's errno attribute, which is present in both Python 2 and Python 3, which means, you don't need different Python 2 vs. 3 logic (I'd argue the intent is a little clearer this way):

import socket
import errno


try:
    do_something()
except socket.error as e:
    if e.errno != errno.EPIPE:
        # Not a broken pipe
        raise
    do_something_about_the_broken_pipe()

If you do care about more than broken pipes, thefourtheye's answer is appropriate and idiomatic.

like image 159
Thomas Orozco Avatar answered Oct 28 '22 00:10

Thomas Orozco