Python улавливает пользовательский класс предупреждений без остановки выполнения кода

#python #error-handling

Вопрос:

Я создаю приложение, которое принимает команду от пользователя, проверяет, является ли команда законной, а затем выполняет команду.

Основной поток заключается в том, что receive_message функция запускается, когда пользователь размещает запрос. receive_message Затем эта функция направляет запрос функции правильной вспомогательной функции в зависимости от того, что запрашивает пользователь.

Есть 2 типа исключительных случаев, которые я хочу обработать-Ошибки и предупреждения. Ошибки должны возникать, когда действие невозможно. Предупреждения должны появляться, когда действие возможно, но потенциально оно будет вести себя не так, как ожидал пользователь.

Прямо сейчас я обрабатываю ошибки, повышая CustomError класс во вспомогательных функциях. Например,

 circularity = is_circular_reference(column_id, reference)
if circularity:
  raise CustomError()
 

Это исключение затем улавливается в receive_message функции, которая имеет следующий код

 try:
       self.handle_request(event)
       self.send({success: True})
         
except CustomError as e:
        print(get_recent_traceback())
        print(e)
        
        response = {
            'event': 'edit_error',
            'id': event['id'],
            'type': e.type_,
            'header': e.header,
            'to_fix': e.to_fix
        }
        
        self.send(response)
 

Я хотел бы иметь возможность обрабатывать CustomWarning это аналогичным образом, с той разницей, что вызов a CustomWarning не должен останавливать выполнение функции. Когда выдается предупреждение, все self.handle_request(event) должно завершиться, а затем я должен поймать предупреждение, чтобы отправить его обратно на интерфейс.

Например, я хочу проверить, следует ли мне выдавать предупреждение таким же образом, как я проверяю наличие ошибок:

 warning_required = is_warning_required(column_id, reference)
if warning_required:
      raise CustomWarning()
 

А затем я хочу расширить receive_message функцию так, чтобы она выглядела следующим образом:

 try:
       self.handle_request(event)
       self.send({success: True})
         
except CustomError as e:
        print(get_recent_traceback())
        print(e)
        
        response = {
            'event': 'edit_error',
            'id': event['id'],
            'type': e.type_,
            'header': e.header,
            'to_fix': e.to_fix
        }
        
        self.send(response)


except CustomWarning as w:
          response = {
                'event': 'edit_warning',
                'id': event['id'],
                'type': e.type_,
                'header': e.header,
                'warning_message': e.warning_message
            }
 

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

1. Как только вы raise , это нарушает текущий поток управления, подобный a return -не имеет значения, что делает вызывающий абонент в except . handle_request это то, что нужно изменить, а не его вызывающий.

Ответ №1:

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

То, что вы хотите, — это handle_request просто создать и вернуть соответствующий ответ.

 try:
    response = self.handle_request(event)
except CustomError as e:
    print(get_recent_traceback())
    print(e)

    response = { ... }

self.send(response)
 

где handle_request само возвращается либо {"success": True} или {"event": "edit_warning", ...} . Как только try оператор будет завершен, response будет ссылаться на соответствующее значение для передачи self.send