Sepertinya saya tidak dapat menemukan banyak informasi tentang kelas pengecualian khusus.
Apa yang saya tahu
Anda bisa mendeklarasikan kelas kesalahan kustom Anda dan membiarkannya StandardError
diturunkan, jadi bisa jadi rescue
d:
class MyCustomError < StandardError
end
Ini memungkinkan Anda untuk meningkatkannya menggunakan:
raise MyCustomError, "A message"
dan nanti, dapatkan pesan itu saat menyelamatkan
rescue MyCustomError => e
puts e.message # => "A message"
Apa yang saya tidak tahu
Saya ingin memberikan pengecualian saya beberapa bidang khusus, tetapi saya ingin mewarisi message
atribut dari kelas induk. Saya menemukan membaca tentang topik ini yang @message
bukan merupakan variabel instance dari kelas pengecualian, jadi saya khawatir warisan saya tidak akan berfungsi.
Adakah yang bisa memberi saya detail lebih lanjut tentang ini? Bagaimana cara menerapkan kelas kesalahan khusus dengan object
atribut? Apakah yang berikut ini benar:
class MyCustomError < StandardError
attr_reader :object
def initialize(message, object)
super(message)
@object = object
end
end
Lalu:
raise MyCustomError.new(anObject), "A message"
mendapatkan:
rescue MyCustomError => e
puts e.message # => "A message"
puts e.object # => anObject
apakah itu akan berhasil, dan jika berhasil, apakah ini cara yang benar dalam melakukan sesuatu?
rescue Exception => e
. Ini lebih luas dari defaultrescue => e
yang diturunkan dariStandardError
, dan menangkap semuanya termasuk Ctrl + C. Aku akan melakukannyarescue MyCustomError => e
.Jawaban:
raise
sudah menyetel pesan sehingga Anda tidak perlu meneruskannya ke konstruktor:Saya telah menggantinya
rescue Exception
denganrescue MyCustomError
, lihat Mengapa gaya `rescue Exception => e` di Ruby merupakan gaya yang buruk? .sumber
rescue Exception
, tapi kenapa tidakrescue MyCustomError
?raise MyCustomError, "a message"
tanpanew
, "pesan" tidak akan disetel.Mengingat apa yang
Exception
dinyatakan oleh dokumentasi inti rubi , yang mewarisi semua kesalahan lainnya, nyatakan#message
http://ruby-doc.org/core-1.9.3/Exception.html#method-i-message
Saya akan memilih untuk mendefinisikan ulang
to_s
/to_str
atau penginisialisasi. Berikut adalah contoh di mana kami ingin tahu, dengan cara yang sebagian besar dapat dibaca manusia, ketika layanan eksternal gagal melakukan sesuatu.CATATAN: Strategi kedua di bawah ini menggunakan metode string rails yang cantik, seperti
demodualize
, yang mungkin sedikit rumit dan karena itu berpotensi tidak bijaksana untuk dilakukan dalam pengecualian. Anda juga bisa menambahkan lebih banyak argumen ke tanda tangan metode, jika Anda membutuhkannya.Mengganti Strategi #to_s bukan #to_str, cara kerjanya berbeda
Output Konsol
Mengganti Strategi #initialize
Ini adalah strategi yang paling dekat dengan implementasi yang saya gunakan di rel. Seperti disebutkan di atas, menggunakan
demodualize
,underscore
danhumanize
ActiveSupport
metode. Tapi ini bisa dengan mudah dihilangkan, seperti pada strategi sebelumnya.Output Konsol
Alat Demo
Ini adalah demo untuk menunjukkan penyelamatan dan pengiriman pesan dari implementasi di atas. Kelas yang memunculkan pengecualian adalah API palsu ke Cloudinary. Cukup buang salah satu strategi di atas ke konsol rel Anda, diikuti dengan ini.
sumber
Ide Anda benar, tetapi cara Anda menyebutnya salah. Harus
sumber
raise
kata kunci atau sesuatu.initialize
untuk mengambil dua argumen.new
meneruskan argumen keinitialize
.raise(BillRowError.new(:roamingcalls, @index), "Roaming Calls field missing")
. Jadi dia memanggilraise
dengan dua parameter:BillRowError
objek baru , dan pesannya. Saya hanya bingung dengan sintaksnya ... Di tutorial lain saya selalu melihatnya seperti ini:raise Error, message
raise
; itu cukup fleksibel. Masalahnya adalah Anda mendefinisikaninitialize
untuk mengambil dua argumen dan hanya memberi satu. Lihat contoh Anda.BillRowError.new(:roamingcalls, @index)
diberikan dua argumen.Saya ingin melakukan hal serupa. Saya ingin meneruskan objek ke #new dan mengatur pesan berdasarkan beberapa pemrosesan objek yang diteruskan. Karya berikut ini.
Perhatikan bahwa jika Anda tidak mendeklarasikannya
attr_accessor :message
maka itu tidak akan berhasil. Mengatasi masalah OP, Anda juga bisa meneruskan pesan sebagai argumen tambahan dan menyimpan apapun yang Anda suka. Bagian krusial tampaknya menggantikan #message.sumber