attic icon indicating copy to clipboard operation
attic copied to clipboard

Exit gracefully when output pipe is broken

Open akhayyat opened this issue 9 years ago • 2 comments

Consider an Attic command with long output, e.g. attic list <repo>::<archive> for an archive with many files.

When the output of such a command is piped to something like less, then you exit less without reaching the end of the output, you get the following backtrace:

$ attic list <repo>::<archive> | less  # and quit less immediately
Traceback (most recent call last):
  File ".../attic", line 3, in <module>
    main()
  File ".../attic/lib/python3.4/site-packages/attic/archiver.py", line 730, in main
    exit_code = archiver.run(sys.argv[1:])
  File ".../attic/lib/python3.4/site-packages/attic/archiver.py", line 720, in run
    return args.func(args)
  File ".../attic/lib/python3.4/site-packages/attic/archiver.py", line 298, in do_list
    remove_surrogates(item[b'path']), extra))
BrokenPipeError: [Errno 32] Broken pipe
Exception ignored in: <_io.TextIOWrapper name='<stdout>' encoding='UTF-8'>
BrokenPipeError: [Errno 32] Broken pipe

From the user's point-of-view, there should not be an error here. It'd be nice if this scenario is handled more gracefully.

akhayyat avatar May 19 '15 18:05 akhayyat

$ python3 -c 'for i in range(1000000): print(i)' | less
Traceback (most recent call last):
  File "<string>", line 1, in <module>
BrokenPipeError: [Errno 32] Broken pipe

I pressed "q" in less after paging down once, but likely before the loop ended.

Python 3.4.0

ThomasWaldmann avatar Sep 19 '15 17:09 ThomasWaldmann

# pipe.py
import errno

try:
    for i in range(1000000):
        print(i)
except IOError as e:
    if e.errno == errno.EPIPE:
        pass

Then, I can press q in less with no errors:

$ python3 pipe.py | less

akhayyat avatar Sep 19 '15 19:09 akhayyat