витой:нет трассировки исключений, если произошла ошибка обратного вызова

StackOverflow https://stackoverflow.com/questions/3826233

Вопрос

Рассмотрим следующий код:

df = defer.Deferred()
def hah(_): raise ValueError("4")
df.addCallback(hah)
df.callback(hah)

Когда он запускается, это исключение просто съедается.Куда это делось?Как я могу заставить его отображаться?Делает defer.setDebugging(True) не имеет никакого эффекта.

Я спрашиваю об этом, потому что иногда получаю распечатку с надписью «Необработанная ошибка в отложенном:».Как мне добиться этого в данном случае?Я вижу, что если я добавлю ошибку в df затем errback вызывается с исключением, но все, что я хочу сделать, это вывести ошибку и больше ничего не делать, и я не хочу вручную добавлять этот обработчик к каждому отложенному вызову, который я создаю.

Это было полезно?

Решение

Исключение все еще находится в Deferred.На данном этапе возможны два результата:

  • Вы можете добавить ошибку в Deferred.Как только вы это сделаете, он будет вызван с ошибкой, содержащей возникшее исключение.
  • Вы можете позволить Deferred собирать мусор (явно удалить df, или вернуться из функции, или потерять ссылку каким-либо другим способом).Это вызывает код «Необработанная ошибка в отложенном».

Поскольку errback может быть добавлен к Deferred в любое время (т.е. первый пункт выше), Deferred не делает ничего сразу с необработанными ошибками.Они не знают, действительно ли ошибка необработана или пока просто необработана.Только когда Deferred собирает мусор, он может быть уверен, что никто другой не будет обрабатывать исключение, поэтому именно тогда оно регистрируется.

В общем, вы хотите быть уверены, что у вас есть ошибки в Deferreds, именно потому, что иногда трудно предсказать, когда Deferred будет собран мусор.Это может занять много времени, а это значит, что может пройти много времени, прежде чем вы узнаете об исключении, если у вас нет собственного прикрепленного сообщения об ошибке.

Это не должно быть ужасным бременем.Любой Deferred (a), который возвращается из обратного вызова на другой Deferred (b) (т. е. когда происходит цепочка), передаст свои ошибки в b.Таким образом, (а) не нужны дополнительные ошибки для регистрации и составления отчетов, нужен только (б).Если у вас есть одна сложная логическая задача, включающая множество асинхронных операций, почти всегда все Deferred’ы, участвующие в этих операциях, должны направлять свои результаты (успех или неудача) в один главный Deferred, который представляет логическую операцию.Часто вам требуется специальное поведение обработки ошибок только для этого одного Deferred'а, и это позволит вам обрабатывать ошибки любого другого задействованного Deferred'а.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top