Skip to content

Handle raising exceptions from PublicTask #4078

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

Merged
merged 3 commits into from
Jun 8, 2018

Conversation

humitos
Copy link
Member

@humitos humitos commented May 9, 2018

When the task raises an exception there is no way to have a custom result under AsyncResult.info, it will be always the Exception that was risen from inside the task.

Because of that, when the task raises an Exception we are handling it inside the run method and we add the exception's message into our custom result without marking the task as FAILURE.

Celery docs: http://docs.celeryproject.org/en/latest/reference/celery.result.html#celery.result.AsyncResult.info

Workaround to #4077

Now, if you revoke the RTD app in your Github service, you will see a nice error message

captura de pantalla_2018-05-09_17-19-16

When the task raises an exception there is no way to have a custom
result under ``AsyncResult.info``, it will be always the Exception
that was risen from inside the task.

Because of that, when the task raises an Exception we are handling it
inside the ``run`` method and we add the exception's message into our
custom result *without marking* the task as FAILURE.
@humitos humitos requested a review from agjohnson May 9, 2018 22:19
@humitos humitos assigned humitos and unassigned humitos May 10, 2018
@humitos
Copy link
Member Author

humitos commented May 11, 2018

As the description says, this is a workaround.

Today I was pointed to use store_result: celery/kombu#573 (comment)

I need to read a little more about that since I'm not familiar.

@humitos
Copy link
Member Author

humitos commented May 11, 2018

That worked, but I think that we still need a way to be able to access the meta information and the exception raised from a FAILURE task. So, it's not only a problem of serialization from my point of view.

I opened this issue upstream looking for help: celery/kombu#868

@humitos
Copy link
Member Author

humitos commented May 15, 2018

I got a reply on the upstream issue that I opened, but I tested and I wasn't able to make it work.

I'd like to merge this PR since it fixes the issue and make it work as it was before and take a deeper look to a better solution later in another PR instead of blocking finding the best solution here.

@humitos humitos requested a review from a team May 23, 2018 15:21
Copy link
Member

@ericholscher ericholscher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a good change, and just something that got missed during Celery upgrades.

Is there a way to add a test for it, so that it doesn't break again? I'm not sure how easily this can be tested though.

if STATUS_UPDATES_ENABLED:
self.update_state(state=status, meta=info)
if error and exception_raised:
info['error'] = str(exception_raised)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason we are passing the string here instead of the actual Exception object? It seems like this limits what we can do with it later on

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I had different problems when trying to serialize an Exception object. In fact, this serialization problem was one of the things that originated this issue.

if error is not None and isinstance(error, Exception):
data['error'] = error.message
if error is not None:
data['error'] = error
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, we should probably we defensive here about what error is. Are we sure it will always be a string type, or should we be actively turning it into a string here, also?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be always a string since that data object here is the info dictionary that we are setting in the run method of the task where we cast the Exception object to a string.

@humitos
Copy link
Member Author

humitos commented May 24, 2018

Is there a way to add a test for it, so that it doesn't break again? I'm not sure how easily this can be tested though.

Mhm, I'm not sure.

I added two different tests. One that tests the result returned when a PublicTask fails and another one that tests the get_status_data function used inside the API endpoint to check the job status works.

It should be good to improve our test coverage on these functionality in another PR, also.

@agjohnson agjohnson merged commit 3a47d63 into master Jun 8, 2018
@agjohnson agjohnson deleted the humitos/celery/public-task-exception-report branch June 8, 2018 20:28
xrmx pushed a commit to italia/docs.italia.it that referenced this pull request Jun 26, 2018
* Handle raising exceptions from PublicTask

When the task raises an exception there is no way to have a custom
result under ``AsyncResult.info``, it will be always the Exception
that was risen from inside the task.

Because of that, when the task raises an Exception we are handling it
inside the ``run`` method and we add the exception's message into our
custom result *without marking* the task as FAILURE.

* Test case for a PublicTask that raises an Exception

* Test case for method used to check a job status
xrmx added a commit to italia/docs.italia.it that referenced this pull request Jun 26, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants