Как попытаться / перехватить возвращаемую транзакцию.on_commit

#python #transactions #return #try-catch

#python #транзакции #Возврат #попробуйте-поймайте

Вопрос:

Я расследую проблему, которую я сузил до одного места внутри метода следующего формата:

 def method_shorthand(properties): 
  some stuff
  some more stuff

  return transaction.on_commit(
      lambda: external_function_call_I_do_not_control(properties))
   )
  

Для конкретного проблемного случая я могу воспроизвести, что external_function_call_I_do_not_control (запуск события сегмента) не происходит / не выполняется успешно, хотя я определил, что вся информация верна вплоть до этого момента. Для этой кодовой базы ‘ATOMIC_REQUESTS’: True, поэтому я предсказываю либо:

  • фиксация на самом деле не происходит (кажется маловероятным; эта функция вызывается как самый последний шаг успешного до этого блока кода)
  • происходит фиксация или нет активной транзакции (в этом случае это просто выполняется), но когда происходит вызов этой функции, это каким-то образом вызывает рвоту — мои деньги на этом

Итак, я хотел бы добавить какой-нибудь блок try / catch в строку этой внешней функции, чтобы, если при ее выполнении возникнет исключение, я мог перехватить это, записать информацию и посмотреть, в чем дело, чтобы я мог это исправить. Проблема в том, что все это находится внутри return transaction.on_commit, поэтому все, что я пробую, кажется неправильным синтаксисом, и, оглядываясь вокруг, я не смог найти пример выполнения этого.

Есть ли безопасный способ добавить блок try / catch внутри этой возвращаемой транзакции.on_commit? Любые другие идеи по устранению неполадок, поскольку фактический вызов функции является внешним, и я не могу изменить код для ведения журнала / отладки?

Ответ №1:

Вместо использования лямбда-выражения используйте целую функцию, которая позволяет выполнять более сложные действия, чем лямбда-выражение (которое обычно представляет собой просто прямую карту ввода -> вывода).

 def method_shorthand(properties): 
  some stuff
  some more stuff

  def oncommit():
      try:
          external_function_call_I_do_not_control(properties)
      except Exception as e:
          # do whatever error handling needs to be done

  return transaction.on_commit(oncommit)
  

Комментарии:

1. Ах, это выглядит как хороший способ разобраться с этим — попробую ответить — спасибо!!!

2. это было очень полезно! Я могу сделать это, как я надеялся, НО эта лямбда была добавлена намеренно прошлой осенью, поэтому я думаю, что это необходимо там (и все виды тестов терпят неудачу, когда я ее удаляю). Похоже, что лямбда используется, когда нам нужно передать функцию (а не результат функции), поэтому мне интересно, смогу ли я выяснить, где / когда она, наконец, выполняется, и добавить свою попытку / except туда вместо этого? Похоже, сегодняшней задачей будет больше узнать о lambda….

3. Как только они были созданы, нет разницы между лямбда-выражением и функцией. Они неразличимы. Единственное отличие заключается в том, что лямбда-выражение может быть записано встроенным и является простым вводом / выводом. Обратите внимание, как transaction.on_commit передается oncommit , не oncommit() — он передает функцию без ее вызова, что аналогично тому, что было бы сделано с лямбда.

4. Я не заметил этого различия — интересно. Я старался держаться как можно ближе к исходному коду (который включает «(свойства)», поэтому я предполагаю, что это выполняет вызов функции) — и просто добавить дополнительную обработку. Необычно ли, что в исходном коде есть лямбда-функция, в которой она действительно выполняет вызов, а не просто передает имя функции?

5. @DianeKaplan Причина, по которой в исходном коде есть лямбда, вероятно, в том, что transaction.on_commit() требуется функция с 0 аргументами, но external_function...() требуется один аргумент. Лямбда-выражение служит посредником, который позволяет вам эффективно превратить функцию с одним аргументом в функцию с нулевым аргументом (поскольку, в конце концов, на момент ее объявления вы уже знаете, что такое properties , поэтому оно с таким же успехом может быть константой).