Исключения Python - перехват всех исключений, кроме ожидаемого

Я работаю над простым скриптом автоматизации на Python, который может генерировать исключения в разных местах. В каждом из них я хотел бы записать конкретное сообщение и выйти из программы. Чтобы сделать это, я поднимаю SystemExit после того, как перехватил исключение и обработал его (выполняя определенные операции регистрации и тому подобное).

В вызове main верхнего уровня я делаю следующее:

if __name__ == "__main__":
    try:
        main()
    except SystemExit:  # handled exception
        sys.exit(1)
    except:  # any unhandled exception
        logging.error('Unexpected error: ', exc_info=True)
        sys.exit(2)

Тем не менее, использование голых, кроме как что-то осуждается. Использует ли "дерево исключений", где я использую голые, кроме как для указания "что-нибудь, кроме исключений, которые я обработал" нестандартным способом? Есть ли лучший способ добиться этого? Я все еще хотел бы регистрировать эти необработанные исключения, даже если они не были обработаны.

Изменить: SystemExit поднимается, чтобы отметить, что исключение было обработано - независимо от того, что исключение в моем случае, я всегда хочу прекратить запуск сценариев, так как любой сбой должен привести к абсолютному отказу.

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

2 ответа

Решение

Голые исключения захватывают вещи, которые вы не хотите ловить, такие как GeneratorExit, Сделайте это так:

except Exception as details:
    logging.error('Unexpected error: {0}'.format(details))

Основная проблема с голым исключением состоит в том, что он может отлавливать такие вещи, как SystemExit и KeyboardInterrupt, которые не являются стандартными ошибками "кода" и обычно не должны обрабатываться так же, как исключение, сгенерированное вашим кодом. Использование класса Exception не охватывает эти случаи, поскольку они не наследуются от него, поэтому это больше, чем синтаксическая разница.

https://docs.python.org/2/howto/doanddont.html https://docs.python.org/3.1/howto/doanddont.html

Если вы хотите обработать эти конкретные случаи, то лучше сделать это явно, как вы это делали для SystemExit.

Это сработало для меня:

try:
   <code>
   raise Exception("my error")
except Exception as e:
    raise e

Если возникает моя ошибка, отображается сообщение об ошибке "моя ошибка". Если возникает неизвестное исключение, отображается текст обработчика исключений по умолчанию. В любом случае возникает исключение и сценарий останавливается.

Другие вопросы по тегам