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

ixxat: can.Notifier/Listener stops on too many errors #1643

Closed
henzef opened this issue Aug 16, 2023 · 13 comments · Fixed by #1645
Closed

ixxat: can.Notifier/Listener stops on too many errors #1643

henzef opened this issue Aug 16, 2023 · 13 comments · Fixed by #1645
Labels

Comments

@henzef
Copy link
Contributor

henzef commented Aug 16, 2023

Describe the bug

I am currently porting my application from python-can 3.3.4 to 4.x and noticed that the IXXAT implementation changed quite a lot. The new version raises much more exceptions than before, which breaks my usecase and I am unsure if there is a non-hacky way to get back the old behaviour.

The issue happens when registering a can.Listener/Notifier as a background thread and the IXXAT reports errors (e.g. because another controller on the bus sends something in a different baudrate). In that case an exception is raised in the receiver thread and it stops, which is permanent even if the bus errors recover.
The old implementation would just continue to call recv() till it succeeds and that's the behaviour I rely on in my code. Would it be possible to add e.g. a config flag to ignore such non-fatal errors?

To Reproduce

Nothing special, just a can.Listener/Notifier and another CAN controller with a different baudrate is sending data on the bus.

Expected behavior

Either non-fatal errors should be:

  • ignored
  • Communicated via some side-channel (e.g. some get_controller_warning_flags() function)
  • Configurable to be disabled

Additional context

OS and version: Windows 10
Python version: 3.9.x
python-can version: 4.2.2
python-can interface/s (if applicable): IXXAT

@henzef henzef added the bug label Aug 16, 2023
@zariiii9003
Copy link
Collaborator

I think that behavior was introduced in #1141
You can implement Listener.on_error() to handle or ignore exceptions.

@henzef
Copy link
Contributor Author

henzef commented Aug 16, 2023

Unfortunately implementing Listener.on_error() does not help here, because the receive-thread is stopped even when the error is handled. see

elif not self._on_error(exc):

@zariiii9003
Copy link
Collaborator

No, the error is raised if the Listeners do not handle the error. Notifier._on_error is not the same as Listener.on_error

@henzef
Copy link
Contributor Author

henzef commented Aug 17, 2023

That's correct, but when Notifier._on_error() calls Listener.on_error() the mainloop of the receiving thread in Notifier._rx_thread has already exited and will not be restarted. The return value of Listener.on_error() just controlls whether Notifier._on_error() raises an error or just logs the exception before exiting

@zariiii9003
Copy link
Collaborator

zariiii9003 commented Aug 17, 2023

I see what you mean. The while loop is inside the try-except block. That's not great 🤔

@zariiii9003
Copy link
Collaborator

@henzef try #1645

@henzef
Copy link
Contributor Author

henzef commented Aug 18, 2023

I tried your patch and it seems to work as intended (so I can ignore these exceptions and the rx thread will continue), but it doesn't seem to fix actually reading from the bus. Did something w.r.t. the initial configuration of the IXXAT change? e.g. to stop after a certain amount of errors? or disabled automatic error recovery?

@zariiii9003
Copy link
Collaborator

I don't really know anything about the IXXAT implementation. Could you provide a traceback of your errors?

@henzef
Copy link
Contributor Author

henzef commented Aug 21, 2023

There is no traceback, but the messages I am waiting for are simply not received (but it works with python-can 3.3.x), instead the log is spammed with the "CAN error: data overrun" warning. When I disable error message generation by removing constants.CAN_OPMODE_ERRFRAME from the initialization, my code works, but I don't think that's the best fix.
I will try to trace the library calls of both python-can versions to see how they are different.

@zariiii9003
Copy link
Collaborator

CAN error: data overrun probably means, that the rx queue is not read fast enough. I'm wondering why that happens, the Notifier should be able to read all messages.
Did you check the CPU load of the Python process?

@henzef
Copy link
Contributor Author

henzef commented Aug 24, 2023

Thanks for merging this fix. I will try to find time to debug my remaining problems in more detail and then create a PR or issue depending on the outcome.

@zariiii9003
Copy link
Collaborator

Oh, i didn't actually intend to close this, sorry. Feel free to reopen 😄

@henzef
Copy link
Contributor Author

henzef commented Aug 24, 2023

No its fine. The described problem is gone, so it should be closed :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants