Bagaimana Anda menyebabkan pengecualian tanpa tertangkap ke output melalui logging
modul daripada ke stderr
?
Saya menyadari cara terbaik untuk melakukan ini adalah:
try:
raise Exception, 'Throwing a boring exception'
except Exception, e:
logging.exception(e)
Tapi situasi saya sedemikian rupa sehingga akan sangat baik jika logging.exception(...)
dipanggil secara otomatis setiap kali pengecualian tidak tertangkap.
python
logging
exception-handling
Jacob Marble
sumber
sumber
Jawaban:
Seperti yang ditunjukkan Ned,
sys.excepthook
dipanggil setiap kali pengecualian muncul dan tidak tertangkap. Implikasi praktis dari hal ini adalah bahwa dalam kode Anda, Anda dapat mengganti perilaku defaultsys.excepthook
untuk melakukan apa pun yang Anda inginkan (termasuk menggunakanlogging.exception
).Sebagai contoh pria jerami:
Timpa
sys.excepthook
:Komit kesalahan sintaksis yang jelas (tinggalkan titik dua) dan dapatkan kembali informasi kesalahan khusus:
Untuk informasi lebih lanjut tentang
sys.excepthook
, baca dokumen .sumber
type
sebagai argumen fungsi, meskipun IDE akan mengeluh tentang menyembunyikan globaltype
(seperti menggunakanvar self = this
Javascript). Tidak masalah kecuali Anda perlu mengaksestype
objek di dalam fungsi Anda, dalam hal ini Anda dapat menggunakantype_
sebagai argumen.sys.excepthook
TIDAK disebut ketika pengecualian "dinaikkan". Disebut ketika program akan berakhir karena pengecualian tanpa tertangkap, yang tidak dapat terjadi lebih dari sekali.Berikut adalah contoh kecil lengkap yang juga mencakup beberapa trik lain:
Abaikan KeyboardInterrupt sehingga program python konsol dapat keluar dengan Ctrl + C.
Bergantung sepenuhnya pada modul logging python untuk memformat pengecualian.
Gunakan logger khusus dengan handler contoh. Yang ini mengubah pengecualian tidak tertangani untuk pergi ke stdout daripada stderr, tetapi Anda bisa menambahkan semua jenis penangan dengan gaya yang sama ke objek logger.
sumber
logger.critical()
di dalam handler excepthook, karena pengecualian tanpa penangkapan cukup penting yang akan saya katakan.logging.basicConfig(level=logging.DEBUG, filename="debug.log", format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
tetapi tidak membantu.Metode
sys.excepthook
ini akan dipanggil jika pengecualian tidak tertangkap: http://docs.python.org/library/sys.html#sys.excepthooksumber
type
instance?sys.excepthook
?Kenapa tidak:
Berikut adalah output dengan
sys.excepthook
seperti yang terlihat di atas:Ini adalah output dengan
sys.excepthook
komentar:Satu-satunya perbedaan adalah bahwa yang pertama ada
ERROR:root:Unhandled exception:
di awal baris pertama.sumber
sys.stderr
.Untuk membangun jawaban Jacinda, tetapi menggunakan objek logger:
sumber
functools.partial()
bukan lambda. Lihat: docs.python.org/2/library/functools.html#functools.partialBungkus panggilan entri aplikasi Anda dalam satu
try...except
blok sehingga Anda dapat menangkap dan mencatat (dan mungkin menaikkan kembali) semua pengecualian yang tidak tertangkap. Misalnya bukannya:Melakukan hal ini:
sumber
Mungkin Anda bisa melakukan sesuatu di bagian atas modul yang mengarahkan ulang stderr ke file, dan kemudian login file itu di bagian bawah
sumber
Meskipun jawaban @ gnu_lorien memberi saya titik awal yang baik, program saya mogok pada pengecualian pertama.
Saya datang dengan solusi yang disesuaikan (dan / atau) yang disempurnakan, yang secara diam-diam mencatat Pengecualian fungsi yang didekorasi
@handle_error
.sumber
Untuk menjawab pertanyaan dari Mr.Zeus yang dibahas di bagian komentar dari jawaban yang diterima, saya menggunakan ini untuk mencatat pengecualian yang tidak tertangkap di konsol interaktif (diuji dengan PyCharm 2018-2019). Saya menemukan
sys.excepthook
tidak bekerja di shell python jadi saya melihat lebih dalam dan menemukan bahwa saya bisa menggunakannyasys.exc_info
. Namun,sys.exc_info
tidak mengambil argumen sepertisys.excepthook
itu membutuhkan 3 argumen.Di sini, saya menggunakan keduanya
sys.excepthook
dansys.exc_info
untuk mencatat pengecualian di konsol interaktif dan skrip dengan fungsi wrapper. Untuk melampirkan fungsi kait ke kedua fungsi, saya memiliki dua antarmuka yang berbeda tergantung apakah argumen diberikan atau tidak.Berikut kodenya:
Setup logging dapat ditemukan di jawaban gnu_lorien.
sumber
Dalam kasus saya (menggunakan
python 3
) ketika menggunakan jawaban @ Jacinda konten traceback tidak dicetak. Sebaliknya, itu hanya mencetak obyek itu sendiri:<traceback object at 0x7f90299b7b90>
.Sebaliknya saya lakukan:
sumber