0

Is this the correct way to catch PermannentTask Failure? (https://cloud.google.com/appengine/articles/deferred)

def do_something_with_key(k):
    entity = k.get()
    # Do something with entity
    entity.put()

k = ndb.Key('MyModel', 123)
try:
   deferred.defer(do_something_with_key, k, _countdown=60)
except PermanentTaskFailure:
   #catch here 

Or do I need to put try/except inside do_something_with_key function

John
  • 3,888
  • 11
  • 46
  • 84

1 Answers1

2

The PermanentTaskFailure exception is typically raised when the task executes or attempts to execute, so you won't catch it when you create the task. Unless, maybe, if you do that from another task execution handler, but in that case it'd be for the enqueueing task, not for the task being enqueued. Or maybe if enqueuing itself has trouble? Not sure - I never got it in such case.

So, at best, I think you might be able to catch it from do_something_with_key(). But you won't be able to catch it for all cases - for example if the task code fails to execute - the exception is caught by the deferred library code itself, see an example in Issue with appengine deferred tasks, execution throws unknown error.

I was able to catch it (again, probably not for all cases), but that was after I switched from the deferred library to directly using the push tasks (which is what the deferred library uses under the hood).

The article you referenced discusses PermanentTaskFailure in the context of your handler code (intentionally) raising the exception to signal to the deferred library that it shouldn't enqueue yet another copy of the task - which is what it does by default if the task execution fails (based on its return code for the request), until the maximum number of retries is reached.

Dan Cornilescu
  • 39,470
  • 12
  • 57
  • 97