diff --git a/hardware/opentrons_hardware/drivers/can_bus/driver.py b/hardware/opentrons_hardware/drivers/can_bus/driver.py index 4552189863d..7d10e475bd0 100644 --- a/hardware/opentrons_hardware/drivers/can_bus/driver.py +++ b/hardware/opentrons_hardware/drivers/can_bus/driver.py @@ -9,6 +9,8 @@ from .arbitration_id import ArbitrationId from .message import CanMessage +from .errors import ErrorFrameCanError + if platform.system() == "Darwin": # TODO (amit, 2021-09-29): remove hacks to support `pcan` when we don't @@ -112,9 +114,15 @@ async def read(self) -> CanMessage: Returns: A can message + + Raises: + ErrorFrameCanError """ ... m: Message = await self._reader.get_message() + if m.is_error_frame: + raise ErrorFrameCanError(message=repr(m)) + return CanMessage( arbitration_id=ArbitrationId(id=m.arbitration_id), data=m.data ) diff --git a/hardware/opentrons_hardware/drivers/can_bus/errors.py b/hardware/opentrons_hardware/drivers/can_bus/errors.py new file mode 100644 index 00000000000..ee70be4304c --- /dev/null +++ b/hardware/opentrons_hardware/drivers/can_bus/errors.py @@ -0,0 +1,15 @@ +"""Can bus errors.""" + + +class CanError(Exception): + """Can bus error.""" + + def __init__(self, message: str) -> None: + """Constructor.""" + super().__init__(message) + + +class ErrorFrameCanError(CanError): + """An error frame was received on the can bus.""" + + pass diff --git a/hardware/tests/opentrons_hardware/drivers/can_bus/test_driver.py b/hardware/tests/opentrons_hardware/drivers/can_bus/test_driver.py index 3d00fb71bb1..1fa16559850 100644 --- a/hardware/tests/opentrons_hardware/drivers/can_bus/test_driver.py +++ b/hardware/tests/opentrons_hardware/drivers/can_bus/test_driver.py @@ -6,6 +6,7 @@ from can import Bus, Message from opentrons_hardware.drivers.can_bus import CanDriver, ArbitrationId, CanMessage +from opentrons_hardware.drivers.can_bus.errors import ErrorFrameCanError @pytest.fixture @@ -89,3 +90,17 @@ async def test_receive_iter(subject: CanDriver, can_bus: Bus) -> None: assert received[0].arbitration_id.id == 0x1FFFFFFF assert received[1].data == bytearray([4, 3, 2, 1]) assert received[1].arbitration_id.id == 0 + + +async def test_raise_error_frame_error(subject: CanDriver, can_bus: Bus) -> None: + """It should raise an error when an error frame is received.""" + m = Message( + arbitration_id=0x1FFFFFFF, + is_extended_id=True, + is_error_frame=True, + is_fd=True, + data=bytearray([1, 2, 3, 4]), + ) + can_bus.send(m) + with pytest.raises(ErrorFrameCanError): + await subject.read()