-
Couldn't load subscription status.
- Fork 257
Ignore exceptions raised in user created tasks #1395
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
base: rolling
Are you sure you want to change the base?
Ignore exceptions raised in user created tasks #1395
Conversation
Signed-off-by: = <[email protected]>
|
yes thank you for this. I ran into this and didn't know enough about the Task system to know if this was expected behavior, so I ended up wrapping my function in an exception catcher, then re-raising it after getting the future. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the PR!
I took some time to understand #1098 better, and I misunderstood it before. I don't think ignoring the exception is the right fix. I think we need to somehow get the executor to get the task awaiting on the one that raised an exception to actually raise it.
Hey @sloretz, sorry for taking the time... We should consider the following cases when a task raises an exception: Managed User-Created TasksFor user-created tasks that are managed—either because another task is awaiting them or a done_callback is attached—the expected behavior (in line with asyncio) is for the exception to be raised in the awaiting task rather than crashing the executor. This is already implemented and to make this work we only need to remove the line in spin() that currently crashes the executor: rclpy/rclpy/rclpy/executors.py Lines 926 to 929 in b74d0a7
Executor-Created Callback TasksFor callback tasks created by the executor (in Unmanaged User-Created TasksBoth asyncio and rclpy insist that all tasks be managed in some form. The asyncio documentation for create_task() even advises:
In both rclpy and asyncio, if an unmanaged task is garbage collected while its exception is unfetched, the exception gets logged. Moreover, it is very hard to understand at runtime if a task is managed. An awaiting task may be polled before the task that raises the exception does so in the same iteration, causing the exception to be caught only in the next iteration of the executor. Also, some users may prefer to deal with the exception in a done callback or by polling the future. |
Addresses #1098.
Currently exceptions raised in user created tasks crash the executor. In my project I had to catch the exception and return it to allow communicating exceptions from the task to the main code.
This pull request mimics the behavior of asyncio, in which exceptions in tasks are ignored and logged upon garbage collection.
The logging part is already implemented, although this code is currently unreachable.
It was only necessary to add a line in the SingleThreadedExecutor to check if the task is related to an entity, since user created tasks are not bounded to any entity.
rclpy/rclpy/rclpy/task.py
Lines 56 to 60 in 4e8b071
@fujitatomoya