Cara menggunakan raise valueerror python

Di dalam tutorial ini kamu akan mempelajari bagaimana menangani kondisi error dalam Python dari keseluruhan sudut pandang sistem. Penanganan error adalah aspek desain yang kritikal, dan itu menyebrangi dari level terendah (terkadang hardware) hingga ke pengguna akhir. Jika kamu tidak memiliki strategi yang konsisten, sistemmu akan tidak dapat diandalkan, pengalaman pengguna akan jelek, dan kamu akan memiliki banyak tantangan dalam debugging dan troubleshooting.

Kunci untuk berhasil adalah menyadari semua aspek yang saling berkaitan ini, mempertimbangkan mereka secara eksplisit, dan membentuk sebuah solusi yang mengenali tiap titik.

Status Codes vs. Exceptions

Ada dua model penanganan error utama: status code dan exception. Status code dapat digunakan oleh bahasa pemrograman apapun. Exception memerlukan dukungan bahasa/runtime.

Python mendukung exception. Python dan librari standarnya menggunakan exception secara liberal untuk melaporkan banyak situasi luar biasa seperti IO error, pembagian dengan nol, indexing di luar batas, dan juga beberapa situasi yang tidak begitu luar biasa seperti akhir iterasi (walaupun itu tersembunyi). Kebanyakan librari akan mengikuti kecocokan dan menaikkan exception.

Itu berarti code-mu akan harus menangani exception yang diangkat oleh Python dan librari, sehingga kamu mungkin juga melakukan raise pada exception dari code-mu jika perlu dan tidak bergantung pada status code.

Contoh Singkat

Sebelum menggali ke dalam tempat suci Python exception dan penerapan terbaik penanganan error, mari kita lihat beberapa penanganan error dalam aksinya:

1def f(): 23 return 4 / 0 4567def g(): def f(): 0def f(): 1def f(): 2def f(): 3def f(): 4def f(): 5def f(): 6def f(): 7def f(): 8def f(): 92021222324252627282930312033343536372639 return 4 / 0 029

Berikut output ketika memanggil 431:

1 return 4 / 0 323 return 4 / 0 645 return 4 / 0 9

Python Exceptions

Python exceptions adalah obyek diatur di dalam sebuah hirarki class:

Berikut adalah keseluruhan hirarkinya:

141234445476750def f(): 0def f(): 153def f(): 3def f(): 456def f(): 5def f(): 659def f(): 8def f(): 9622122652425682728713031743334773637def g(): 039 return 4 / 0 0def g(): 3def g(): 4def g(): 5def g(): 6def g(): 7def g(): 8def g(): 9def f(): 00def f(): 01def f(): 02def f(): 03def f(): 04def f(): 05def f(): 06def f(): 07def f(): 08def f(): 09def f(): 10def f(): 11def f(): 12def f(): 13def f(): 14def f(): 15def f(): 16def f(): 17def f(): 18def f(): 19def f(): 20def f(): 21def f(): 22def f(): 23def f(): 24def f(): 25def f(): 26def f(): 27def f(): 28def f(): 29def f(): 30def f(): 31def f(): 32def f(): 33def f(): 34def f(): 35def f(): 36def f(): 37def f(): 38def f(): 39def f(): 40def f(): 41def f(): 42def f(): 43def f(): 44def f(): 45def f(): 46def f(): 47def f(): 48def f(): 49def f(): 50def f(): 51def f(): 52def f(): 53def f(): 54def f(): 55def f(): 56def f(): 57def f(): 58def f(): 59def f(): 60def f(): 61def f(): 62def f(): 63def f(): 64def f(): 65def f(): 66def f(): 67def f(): 68def f(): 69def f(): 70def f(): 71def f(): 72def f(): 73def f(): 74def f(): 75def f(): 76def f(): 77def f(): 78def f(): 79def f(): 80def f(): 81def f(): 82def f(): 83def f(): 84def f(): 85def f(): 86def f(): 87def f(): 88def f(): 89def f(): 90def f(): 91def f(): 92def f(): 93def f(): 94def f(): 95def f(): 96def f(): 97def f(): 98def f(): 99200

Ada beberapa exception khusus yang diturunkan secara langsung dari 432, seperti 433, 434 dan 435. Kemudian ada 436 class, yaitu class dasar untuk 437, 438 dan 439. Semua error standard diturunkan dari 438.

Ketika kamu menaikkan sebuah exception atau beberapa fungsi yang kamu panggil menaikkan sebuah exception, alur code normal itu mulai menyebarkan kumpulan panggilan hingga itu menghadapi exception handler yang pantas. Jika tidak ada exception handler yang tersedia untuk menanganinya, proses (atau lebih akuratnya thread terkini) akan dimatikan dengan sebuah pesan exception yang tidak dapat ditangani.

Menaikkan Exceptions

Melakukan raise pada exception sangat mudah. Kamu hanya perlu menggunakan kata kunci 441 untuk menaikkan sebuah obyek yaitu sebuah sub-class dari class 436. Itu dapat berapa sebuah contoh 436 itu sendiri, satu dari exception standar (misalnya 444), atau sebuah subclass dari 436 yang kamu turunkan sendiri. Berikut snippet kecil yang mendemonstrasikan semua kasus:

1202232054567210def f(): 0def f(): 1213def f(): 3def f(): 4def f(): 5def f(): 6218def f(): 8def f(): 922121222425226272822930312323334235363739 return 4 / 0 0def g(): 4def g(): 5242

Menangkap Exceptions

Kamu menangkap exception dengan klausul 446, seperti yang kamu lihat di dalam contoh. Ketika kamu menangkap sebuah exception, kamu memiliki tiga pilihan:

  • Menelan itu secara diam (menangani itu dan tetap berjalan).
  • Melakukan sesuatu seperti logging, namun menaikkan kembali exception yang sama untuk mengijinkan penanganan tingkat yang lebih tinggi.
  • Menaikkan exception yang berbeda alih-alih original.

Menelan Exception

Kamu hendaklah menelan exception jika kamu tahu bagaimana menanganinya dan dapat menyembuhkan secara penuh.

Sebagai contoh, jika kamu menerima sebuah file input yang mungkin dalam format berbeda (JSON, YAML), kamu mungkin mencoba mengurainya menggunakan parser yang berbeda. Jika parser JSON menaikkan sebuah exception dimana file bukan merupakan file JSON yang valid, kamu menelannya dan mencobanya dengan parser YAML. Jika parser YAML gagal juga maka kamu mengijinkan exception menyebar keluar.

1244232474567252def f(): 0def f(): 120def f(): 3def f(): 4258def f(): 5def f(): 6261def f(): 8def f(): 9264

Perhatikan bahwa exception lainnya (misalnya file tidak ditemukan atau tidak ada ijin membaca) akan menyebar dan tidak akan ditangkap oleh klausul except spesifik. Ini adalah kebijakan yang baik dalam kasus ini dimana kamu ingin mencoba YAML melakukan parsing hanya jika JSON gagal dikarenakan permasalahan encoding JSON.

Jika kamu ingin menangani semua exception maka cukup gunakan 447. Sebagai contoh:

12662320452726726def f(): 0def f(): 1278

Perhatikan bahwa dengan menambahkan 448, kamu mengikat obyek exception ke nama 449 yang tersedia di dalam klausul except.

Menaikkan Ulang Exception Yang Sama

Untuk menaikkan ulang, cukup tambahkan 441 tanpa argument di dalam handlermu. Ini membiarkanmu melakukan penanganan lokal yang sama, namun tetap membiarkan level yang lebih atas menanganinya juga. Di sini, function 451 mencetak jenis exception ke console dan kemudian menaikkan ulang exception.

12802320452726726def f(): 0def f(): 1278def f(): 3def f(): 4295

Menaikkan Exception Yang Berbeda

Ada beberapa kasus dimana kamu akan ingin menaikkan exception yang berbeda. Terkadang kamu ingin melakukan group banyak exception level rendah yang berbeda ke dalam sebuah kategori tunggal yang ditangani secara seragam oleh code level lebih tinggi. Dalam urutan kasus, kamu perlu mengubah exception ke level pengguna dan menyediakan beberapa konteks yang spesifik pada aplikasi.

Klausul Finally

Terkadang kamu ingin memastikan beberapa code pembersih berjalan bahkan jika sebuah exception dinaikkan di suatu tempat sepanjang proses. Misalnya, kamu mungkin memiliki sebuah hubungan database yang kamu ingin tutup setelah selesai. Berikut cara yang salah untuk melakukannya:

1297233004530367306

Jika function 452 menaikkan sebuah exception maka panggilan ke 453 tidak akan pernah dieksekusi dan DB connection akan tetap terbuka. Klausul 454 selalu dieksekusi setelah percobaan semua exception handler dieksekusi. Berikut cara melakukannya dengan benar:

129723311452067317def f(): 0def f(): 1320def f(): 3def f(): 4323def f(): 5def f(): 6326def f(): 8def f(): 9329

Panggilan ke 455 mungkin tidak mengembalikan sebuah koneksi atau menaikkan exception itu sendiri. Di dalam kasus ini tidak perlu menutup DB connection.

Ketika menggunakan 454, kamu harus berhati-hati tidak menaikkkan exception apapun di sana karena mereka akan menutupi exception original.

Context Managers

menyediakan mekanisme lainnya untuk membungkus sumber seperti file atau DB connections dalam code pembersih yang berjalan secara otomatis bahkan ketika exception telah dinaikkan. Alih-alih blok try-finally, kamu menggunakan pernyataan 457. Berikut adalah sebuah contoh dengan file:

13312333445337

Sekarang, bahkan jika 458 menaikkan sebuah exception, file akan ditutup dengan benar secara langsung ketika ruang lingkup blok 457 keluar, terlepas apakah exception ditangani atau tidak.

Logging

Logging cukup banyak merupakan persyaratan dalam sistem tidak sepele yang berjalan lama. Itu khususnya berguna di dalam aplikasi web dimana kamu dapat memperlakukan semua exception di dalam cara umum: Cukup lakukan log pada exception dan kembalikan sebuah pesan error kepada pemanggil.

Ketika melakukan logging, itu berguna untuk melakukan log jenis exception, pesan error, dan stacktrace. Semua informasi ini tersedia via obyek 460, namun jika kamu menggunakanmetode  461 di dalam exception handler, sistem logging Python akan mengekstrak semua informasi yang relevan untukmu.

Ini adalah pelaksanaan terbaik yang saya rekomendasikan:

1339233424567def f(): def f(): 0def f(): 120def f(): 3def f(): 4353def f(): 5def f(): 6356def f(): 8def f(): 93592122295

Jika kamu mengikuti pola ini maka (dengan mengasumsikan kamu mengatur logging dengan benar) tidak peduli apa yang terjadi kamu akan memiliki catatan yang cukup baik di dalam log akan apa yang salah, dan kamu akan dapat memperbaiki permasalahan itu.

Jika kamu menaikkan ulang, pastikan kamu tidak melakukan log exception yang sama berulang-ulang pada tingkatan yang berbeda. Itu adalah pemborosan, dan itu mungkin membingungkanmu dan membuatmu berpikir banyak contoh permasalahan yang sama terjadi, ketika di dalam praktik sebuah contoh tunggal dicatat ke dalam log berulang kali.

Cara paling sederhana untuk melakukan itu adalah membiarkan semua exception menyebar (kecuali jika mereka dapat ditangani secara percaya diri dan ditelan sebelumnya) dan kemudian lakukan logging dekat dengan level teratas aplikasi/sistemmu.

Sentry

Logging adalah sebuah kapabilitas. Penerapan yang paling umum adalah menggunakan file log. Namun, untuk sistem terdistribusi skala besar dengan ratusan, ribuan atau lebih server, ini tidak selalu merupakan solusi terbaik.

Untuk melacak exception sepanjang keseluruhan infrastruktur, sebuah layanan seperti sentry itu super berguna. Itu memusatkan semua laporan exception, dan dalam tambahan ke stacktrace itu menambahkan keadaan tiap stack frame (nilai variabel pada waktu exception dinaikkan). Itu juga menyediakan sebuah tampilan yang sangat bagus dengan dashboard, laporan dan cara untuk memecah pesan oleh banyak project. Itu open source, sehingga kamu dapat menjalankan servermu sendiri atau berlangganan ke versi host.

Menangani Kegagalan Sementara

Beberapa kegagalan itu sementara, khususnya ketika menangani sistem terdistribusi. Sebuah sistem yang menakutkan pada tanda pertama masalah itu tidak berguna.

Jika code-mu mengakses beberapa sistem jarak jauh yang tidak merespon, solusi tradisional adalah timeout, namun terkadang tidak semua sistem didesain dengan timeout. Timeout tidak selalu mudah untuk dikalibrasi saat kondisi berubah.

Pendekatan lainnya adalah gagal dengan cepat kemudian mencoba ulang. Manfaatnya adalah jika target merespon cepat maka kamu tidak harus menghabiskan banyak waktu dalam kondisi tidur dan dapat bereaksi secara langsung. Namun jika itu gagal, kamu dapat mencoba ulang berkali-kali hingga kamu memutuskan itu benar-benar tidak dapat diraih dan menaikkan sebuah exception. Di dalam section berikutnya, saya akan memperkenalkan sebuah decorator yang dapat melakukan itu untukmu.

Decorator Yang Berguna

Dua decorator yang dapat membantu dengan penanganan error adalah 462, yang melakukan log sebuah exception dan kemudian menaikkan ulang itu, dan decorator 463, yang akan mencoba ulang memanggil sebuah function beberapa kali.

Error Logger

Berikut adalah penerapan sederhananya. Decorator mengecualikan obyek logger. Ketika itu mendekorasi sebuah function dan function dipanggil, itu akan membungkus panggilan dalam sebuah klausul try-except, dan jika ada sebuah exception itu akan melakukan log lagi dan akhirnya menaikkan ulang exception.

1364233674537067373def f(): 0def f(): 1376def f(): 3def f(): 4379def f(): 5def f(): 6382def f(): 8def f(): 93852122388242539127283943031397

Berikut bagaimana menggunakannya:

1339233424567 return 4 / 0 07def f(): 0def f(): 1def f(): def f(): 3def f(): 4 return 4 / 0 13

Retrier

Berikut adalah penerapan yang bagus dari .

1 return 4 / 0 1523 return 4 / 0 184567 return 4 / 0 23def f(): 0def f(): 1 return 4 / 0 26def f(): 3def f(): 4 return 4 / 0 29def f(): 5 return 4 / 0 31def f(): 6 return 4 / 0 31def f(): 8 return 4 / 0 31def f(): 9 return 4 / 0 3721 return 4 / 0 3122 return 4 / 0 4124 return 4 / 0 3125 return 4 / 0 4527 return 4 / 0 3128 return 4 / 0 4930313334 return 4 / 0 543637 return 4 / 0 5739 return 4 / 0 0def g(): 4def g(): 5 return 4 / 0 62def g(): 7def g(): 8 return 4 / 0 65def f(): 00def f(): 01 return 4 / 0 68def f(): 03def f(): 04def f(): 06def f(): 07 return 4 / 0 73def f(): 09def f(): 10 return 4 / 0 76def f(): 12def f(): 13def f(): 15def f(): 16 return 4 / 0 81def f(): 18def f(): 19 return 4 / 0 84def f(): 21def f(): 22 return 4 / 0 87def f(): 24def f(): 25def f(): 27def f(): 28 return 4 / 0 92def f(): 30def f(): 31 return 4 / 0 95def f(): 33def f(): 34 return 4 / 0 98def f(): 36def f(): 37401def f(): 39def f(): 40def f(): 42def f(): 43406def f(): 45def f(): 46409def f(): 48def f(): 49412def f(): 51def f(): 52def f(): 54def f(): 55417def f(): 57def f(): 58def f(): 60def f(): 61422def f(): 63def f(): 64def f(): 66def f(): 67427def f(): 69def f(): 70430

Kesimpulan

Penanganan error itu krusial baik bagi pengguna dan pengembang. Python menyediakan dukungan yang baik dalam bahasa dan librari standar untuk penanganan error berbasis exception. Dengan mengikuti penerapan terbaik secara pintar, kamu dapat menaklukkan aspek yang sering diabaikan ini.

Postingan terbaru

LIHAT SEMUA