hardbyte / hardbyte/python-can

Catching Exceptions in the Listener

Offen
#1,675 2 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
bug
Vorherrschende Sprache
Python
Sterne
1.6k
Forks
697
PR-Merge-Kennzahlen
Keine gemergten PRs in 30 T.

Beschreibung

### Describe the bug
This may be similar to #1667

Occasionally when other devices on the CAN Bus are rebooted or turned, we see the TX buffer get full and this OS forces the CAN Bus to go down. This is expected and I am trying to catch this in code allow the code to restart and reconnect.

I can catch the `Exception` when connecting to the CAN Bus and sending a message, however when the exception is passed to the `Listener.on_error` this is within a thread, and therefore when I call `sys.exit(1)` the application keeps running.

I am unable to find an error handler on the `Bus` object where is exception will be propagated or any other way to handle this Exception.

`os._exit()` will work, but is not recommended.

### To Reproduce

With the following code receiving CAN Messages, execute `ifdown can0` in a different terminal.

```python
class NewMessageListener(Listener):

def __init__(self, fn_new_message_notify: callable):

Listener.__init__(self)
self.fn_new_message_notify = fn_new_message_notify

def on_message_received(self, msg: Message) -> None:
try:
self.fn_new_message_notify(msg)

except RuntimeError as e:
_logger.error("Error with runtime: %s", e)

except Exception as e: # pylint: disable=W0703
_logger.exception("Exception from handler: %s", e)

def on_error(self, exc: Exception) -> None:
if isinstance(exc, (CanOperationError, ValueError, OSError)):
_logger.critical("CAN Bus Error from receiver: %s", exc)
sys.exit(1)

_logger.exception(exc)
sys.exit(1)
```

Without the logging obscuring the Exception the error is:
```
Exception in thread can.notifier for bus "socketcan channel 'can0'":
Traceback (most recent call last):
File "/root/.local/lib/python3.8/site-packages/can/interfaces/socketcan/socketcan.py", line 531, in capture_message
cf, ancillary_data, msg_flags, addr = sock.recvmsg(
OSError: [Errno 100] Network is down

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/local/lib/python3.8/threading.py", line 932, in _bootstrap_inner
self.run()
File "/usr/local/lib/python3.8/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "/root/.local/lib/python3.8/site-packages/can/notifier.py", line 122, in _rx_thread
msg = bus.recv(self.timeout)
File "/root/.local/lib/python3.8/site-packages/can/bus.py", line 98, in recv
msg, already_filtered = self._recv_internal(timeout=time_left)
File "/root/.local/lib/python3.8/site-packages/can/interfaces/socketcan/socketcan.py", line 739, in _recv_internal
msg = capture_message(self.socket, get_channel)
File "/root/.local/lib/python3.8/site-packages/can/interfaces/socketcan/socketcan.py", line 539, in capture_message
raise can.CanOperationError(f"Error receiving: {error.strerror}", error.errno)
can.exceptions.CanOperationError: Error receiving: Network is down [Error Code 100]
```

### Expected behavior
Either:
* The Exception to be passed to the Bus (or other top level object) to be handled
* A graceful way to close the application.

### Additional context

OS and version: Raspberry Pi Running Docker python:3.8-slim-buster
Python version: 3.8
python-can version: ~4.1
python-can interface/s (if applicable):

Beitragsleitfaden

Beitragsleitfaden öffnen

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.