витая: нет трассировки исключений, если ошибка от обратного вызова - PullRequest
2 голосов
/ 30 сентября 2010

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

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

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

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

1 Ответ

6 голосов
/ 30 сентября 2010

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

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

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

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

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

...