Repository: ultrabug/py3status

Issue:
Runtime error (BrokenPipeError) helpers.py line 11
When restarting i3 using `i3 restart`, error bar pops up with message `py3status: Runtime error (BrokenPipeError) helpers.py line 11. Please try to fix this and reload i3wm (Mod+Shift+R)`

Everything appears to be functioning and the bar still shows.

Running Ubuntu 16.04
py3status 3.1
python 3.5.2



Discussion:
Hi @Goodpie 

Would you mind sharing the version of py3status you're running please ?

@ultrabug 3.1 with Python 3.5.2

@Goodpie thanks, since quite a few runtime bug fixes got fixed in 3.2, would you please be able to test with the latest version & report back ?

Thanks a lot

@ultrabug Issue still present in 3.2 and 3.3rc0

hmm so strange I can't reproduce it, I'll dig in...

Just to help me pinpoint or get an idea @Goodpie, do you use a lot of modules ?

Do you experience the issue when running an almost empty config ?

Was using [this config](https://gist.github.com/Goodpie/0055673041488ccddbba02e89c0a54d3) at the time of posting the error.

Tried removing all and the error still persists (obviously with the additional no modules error). Tried adding 1 at a time, starting with the "hello_world" module and no matter which one was there, the error still persisted. Tried replacing a lot of modules with the ones listed on your [modules page](https://github.com/ultrabug/py3status/blob/master/py3status/modules/README.md) but still no luck.

Will something like (in helpers.py)

```
def print_line(line):
    """
    Print given line to stdout (i3bar).
    """
    try:
        sys.__stdout__.write('{}\n'.format(line))
        sys.__stdout__.flush()
    except IOError:
        # i3bar has exited.
        pass
```

fix the issue

@tobes I thought that fixed the issue but the error bar was just really delayed, 

@ultrabug I managed to get the stack trace

```
016-10-30 21:39:00 WARNING Runtime error (BrokenPipeError) helpers.py line 11.
2016-10-30 21:39:00 INFO Traceback
BrokenPipeError: [Errno 32] Broken pipe
  File "/usr/local/lib/python3.5/dist-packages/py3status-3.2-py3.5.egg/py3status/__init__.py", line 37, in main
    py3.run()
  File "/usr/local/lib/python3.5/dist-packages/py3status-3.2-py3.5.egg/py3status/core.py", line 751, in run
    print_line(',[{}]'.format(out))
  File "/usr/local/lib/python3.5/dist-packages/py3status-3.2-py3.5.egg/py3status/helpers.py", line 11, in print_line
    sys.__stdout__.flush()

2016-10-30 21:39:00 ERROR py3status: Runtime error (BrokenPipeError) helpers.py line 11. Please try to fix this and reload i3wm (Mod+Shift+R)
2016-10-30 21:39:00 INFO lock cleared, exiting
```

Okay @Goodpie then in the code of @tobes just change the IOError exception to `BrokenPipeError` please and see if it works better ?

Yeah it seems to have worked. I don't know why I didn't just do that in the first place. Thanks for the help.

I experienced this same issue today. Catching the `BrokenPipeError` error and passing on it gets rid of the error message, but also prevents py3status from doing anything.

This appears to be caused by libconfuse. I'm on Arch Linux, which just pushed out confuse 3.0. Downgrading to confuse 2.8 fixes the issue. I have not looked into it further to see what changes in confuse caused this.


Resolving patch:
diff --git a/py3status/__init__.py b/py3status/__init__.py
--- a/py3status/__init__.py
+++ b/py3status/__init__.py
@@ -9,6 +9,13 @@
 except ImportError:
     pass
 
+try:
+    # python3
+    IOPipeError = BrokenPipeError
+except NameError:
+    # python2
+    IOPipeError = IOError
+
 
 def main():
     try:
@@ -21,9 +28,9 @@ def main():
     try:
         py3 = Py3statusWrapper()
         py3.setup()
-    except KeyboardInterrupt:
+    except (IOPipeError, KeyboardInterrupt):
         if py3:
-            py3.notify_user('Setup interrupted (KeyboardInterrupt).')
+            py3.notify_user('Setup interrupted')
         sys.exit(0)
     except Exception as e:
         if py3:
@@ -35,11 +42,11 @@ def main():
 
     try:
         py3.run()
+    except (IOPipeError, KeyboardInterrupt):
+        pass
     except Exception:
         py3.report_exception('Runtime error')
         sys.exit(3)
-    except KeyboardInterrupt:
-        pass
     finally:
         py3.stop()
         sys.exit(0)


Test patch: