Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't catch the SerialException we just raised #494

Merged
merged 1 commit into from
Sep 14, 2020

Conversation

kalvdans
Copy link

In Python3 we get double tracebacks for this error:

Traceback (most recent call last):
  File "/home/chn/repo/pyserial/serial/serialposix.py", line 557, in read
    raise SerialException(
serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected or multiple access on port?)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test/test_exceptions.py", line 26, in <module>
    test_unexpected_eof()
  File "/usr/lib/python3.8/unittest/mock.py", line 1348, in patched
    return func(*newargs, **newkeywargs)
  File "test/test_exceptions.py", line 21, in test_unexpected_eof
    s.read()
  File "/home/chn/repo/pyserial/serial/serialposix.py", line 566, in read
    raise SerialException('read failed: {}'.format(e))
serial.serialutil.SerialException: read failed: device reports readiness to read but returned no data (device disconnected or multiple access on port?)

The patch moves the checking for EOF to after the IO block, resulting
in a much nicer traceback. This is the test script (Python3-specific):

from unittest import mock
import serial
import select
import os

@mock.patch('select.select')
@mock.patch('os.read')
def test_unexpected_eof(mock_read, mock_select):
    s = serial.Serial()
    s.is_open = True
    s.fd = 99
    s.pipe_abort_read_r = 98
    mock_select.return_value = ([99],[],[])
    mock_read.return_value = b''
    try:
        s.read()
    except serial.SerialException as e:
        if e.__context__: raise

if __name__ == '__main__':
    test_unexpected_eof()

In Python3 we get double tracebacks for this error:

Traceback (most recent call last):
  File "/home/chn/repo/pyserial/serial/serialposix.py", line 557, in read
    raise SerialException(
serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected or multiple access on port?)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test/test_exceptions.py", line 26, in <module>
    test_unexpected_eof()
  File "/usr/lib/python3.8/unittest/mock.py", line 1348, in patched
    return func(*newargs, **newkeywargs)
  File "test/test_exceptions.py", line 21, in test_unexpected_eof
    s.read()
  File "/home/chn/repo/pyserial/serial/serialposix.py", line 566, in read
    raise SerialException('read failed: {}'.format(e))
serial.serialutil.SerialException: read failed: device reports readiness to read but returned no data (device disconnected or multiple access on port?)

The patch moves the checking for EOF to after the IO block, resulting
in a much nicer traceback. This is the test script (Python3-specific):

from unittest import mock
import serial
import select
import os

@mock.patch('select.select')
@mock.patch('os.read')
def test_unexpected_eof(mock_read, mock_select):
    s = serial.Serial()
    s.is_open = True
    s.fd = 99
    s.pipe_abort_read_r = 98
    mock_select.return_value = ([99],[],[])
    mock_read.return_value = b''
    try:
        s.read()
    except serial.SerialException as e:
        if e.__context__: raise

if __name__ == '__main__':
    test_unexpected_eof()
@zsquareplusc
Copy link
Member

Makes sense. Thank you

@zsquareplusc zsquareplusc merged commit 9e9bceb into pyserial:master Sep 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants