0

I have a long running task that may raise an exception randomly. This task is an infinite loop: it's not expected to finish or to be awaited. It is tied to an instance of a specific class, I cancel the task when the instance is garbage collected.

I'd like to raise potential errors "outside" of this task but failed to do so.

    def start_worker(self):
        self.worker = asyncio.create_task(
            self._worker()
        )
        def should_never_be_done(t: asyncio.Task):
            if t.exception() is not None:
                logger.exception(t.exception())
                raise t.exception()
            raise Exception(
                "_worker task is done, yet it should never finish")
        self.worker.add_done_callback(should_never_be_done)

I see the exception in my log, but it doesn't crash the whole app, which I want in this case instead of a silent fail leading to infinite loadings in my UI.

This related question show only how to log the error but do not aim at raising it, hence the separate question.

4
  • In Python 3.11, use the context manager for this. Commented Jul 4, 2023 at 16:17
  • Please provide a minimal reproducible example. The code snippet here is neither complete nor does it communicate what you described in prose. It is just a dump of a few lines of your program. Commented Jul 4, 2023 at 16:27
  • Also, this seems like a duplicate of this question. Just don't leave a task dangling without eventually awaiting it somewhere. Commented Jul 4, 2023 at 16:44
  • Right for the duplicate, the answer is not satisfactory as it imply awaiting the tasks but the question is indeed similar. Commented Jul 11, 2023 at 11:34

1 Answer 1

1

well, the add_done_callback is as good as it gets: if you see the exception in your logs, you had catch the exception - now, just do whatever you want with it.

Either just relaunch your worker, or create an event or queue with which you can sinalize to the rest of the application they should be done, or, to just crash everything, just close the event loop right there:

        ...
        def should_never_be_done(t: asyncio.Task):
            if t.exception() is not None:
                logger.exception(t.exception())
                # Trainwreck: 
                asyncio.get_running_loop().close()
                
Sign up to request clarification or add additional context in comments.

1 Comment

I think the "trainwreck" part is what I missed : feel free to add this answer in stackoverflow.com/questions/66293545/… which seems to be the same question

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.