#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
, это нарушает текущий поток управления, подобный areturn
-не имеет значения, что делает вызывающий абонент в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