สามารถกู้คืนข้อยกเว้นที่ยกมาเพื่อป้องกันไม่ให้แอปพลิเคชันของคุณหยุดทำงานเมื่อถึงด้านบนสุดของสแต็กการโทร ใน Ruby เราใช้ rescue
คำสำคัญสำหรับสิ่งนั้น
เมื่อช่วยเหลือข้อยกเว้นใน Ruby คุณสามารถระบุคลาสข้อผิดพลาดเฉพาะที่ควรได้รับการช่วยเหลือ
begin
raise 'This exception will be rescued!'
rescue StandardError => e
puts "Rescued: #{e.inspect}"
end
หมายเหตุ :เมื่อใช้ raise
โดยไม่ระบุคลาสข้อยกเว้น Ruby จะใช้ค่าเริ่มต้นเป็น RuntimeError
.
นอกจากการระบุคลาสข้อยกเว้นเดียวเพื่อช่วยเหลือแล้ว คุณยังสามารถส่งอาร์เรย์ของคลาสข้อยกเว้นไปยัง rescue
คำสำคัญ. วิธีนี้จะช่วยให้คุณตอบสนองต่อข้อผิดพลาดหลายข้อในลักษณะเดียวกันได้
begin
raise 'This exception will be rescued!'
rescue StandardError, AnotherError => e
puts "Rescued: #{e.inspect}"
end
rescue
หลายรายการ สามารถใช้บล็อกเพื่อจัดการกับข้อผิดพลาดต่างๆ ในรูปแบบต่างๆ ได้ ซึ่งจะมีประโยชน์เมื่อทำงานกับไลบรารีที่สร้างข้อยกเว้นที่แตกต่างกันสำหรับสถานการณ์ต่างๆ
begin
raise 'This exception will be rescued!'
rescue StandardError => e
puts "Rescued: #{e.inspect}"
rescue AnotherError => e
puts "Rescued, but with a different block: #{e.inspect}"
end
ลำดับชั้นข้อยกเว้น
ลำดับชั้นข้อยกเว้นของ Ruby ใช้เพื่อแยกความแตกต่างระหว่างข้อผิดพลาดประเภทต่างๆ ในขณะที่ให้ความสามารถในการช่วยเหลือจากกลุ่มข้อผิดพลาดโดยไม่ต้องระบุข้อผิดพลาดทั้งหมด
แม้ว่าไลบรารี่สามารถกำหนดคลาสย่อยข้อยกเว้นของตนเองได้ แต่รายการของคลาสย่อยข้อยกเว้นในตัวบน Ruby 2.5 จะมีลักษณะดังนี้:
- NoMemoryError
- ScriptError
- LoadError
- NotImplementedError
- SyntaxError
- SecurityError
- SignalException
- Interrupt
- StandardError (default for `rescue`)
- ArgumentError
- UncaughtThrowError
- EncodingError
- FiberError
- IOError
- EOFError
- IndexError
- KeyError
- StopIteration
- LocalJumpError
- NameError
- NoMethodError
- RangeError
- FloatDomainError
- RegexpError
- RuntimeError (default for `raise`)
- SystemCallError
- Errno::*
- ThreadError
- TypeError
- ZeroDivisionError
- SystemExit
- SystemStackError
- fatal (impossible to rescue)
เมื่อละเว้นคลาสข้อยกเว้นใน rescue
บล็อก StandardError
จะถือว่า เพราะ ArgumentError
และ NoMethodError
เป็นคลาสย่อยของ StandardError
สิ่งเหล่านี้จะได้รับการช่วยเหลือเมื่อเกิดขึ้นในบล็อก
ตัวอย่างที่ดีเกี่ยวกับวิธีการทำงานของลำดับชั้นข้อยกเว้นคือ SystemCallError
ซึ่งเป็นคลาสข้อยกเว้นที่ขึ้นกับแพลตฟอร์มระดับต่ำ พบบ่อยที่สุดเมื่ออ่านหรือเขียนไปยังไฟล์
File.read
ของ Ruby เมธอดจะทำให้เกิดข้อยกเว้นหากไม่สามารถอ่านไฟล์ได้ ที่อาจเกิดขึ้นได้จากหลายสาเหตุ เช่น ไฟล์ไม่มีอยู่หรือโปรแกรมไม่มีสิทธิ์ในการอ่านที่ถูกต้อง
เนื่องจากปัญหาเหล่านี้ขึ้นอยู่กับแพลตฟอร์ม Ruby จึงสามารถยกข้อยกเว้นต่างๆ ขึ้นได้ขึ้นอยู่กับชนิดของระบบปฏิบัติการที่รันอยู่บนเครื่อง สำหรับข้อผิดพลาดระดับต่ำเช่นนี้ Ruby ใช้รายการ Errno::*
ที่แตกต่างกัน -ข้อยกเว้นสำหรับแต่ละแพลตฟอร์ม
Errno::*
. ทั้งหมดนี้ ข้อยกเว้นคือคลาสย่อยของ SystemCallError
. แม้ว่าจะเป็นเฉพาะแพลตฟอร์ม แต่ก็ยังใช้ใน rescue
. ได้ บล็อกโดยการช่วยเหลือจาก SystemCallError
.
begin
File.read("does/not/exist")
rescue SystemCallError => e
puts "Rescued: #{e.inspect}"
end
ข้อยกเว้นการกลืน
โดยปกติ เป็นการดีที่สุดที่จะระบุให้เฉพาะเจาะจงที่สุดเท่าที่จะทำได้เมื่อช่วยเหลือข้อยกเว้น เพื่อป้องกันข้อยกเว้นกลืนโดยไม่ตั้งใจ
image = nil
begin
File.read(image.filename)
rescue
puts "File can't be read!"
end
ในตัวอย่างนี้ image
ตัวแปร nil
ดังนั้นจึงทำให้เกิด NoMethodError
เมื่อเราพยายามเรียก #filename
กับมัน (NoMethodError: undefined method `filename' for nil:NilClass
). เพราะทุก StandardError
คลาสย่อยได้รับการช่วยเหลือจาก (รวมถึง NoMethodError
) ระบบจะกลืนข้อยกเว้นและพิมพ์ข้อความ "ไม่สามารถอ่านไฟล์ได้!" สิ่งนี้ซ่อนข้อบกพร่องที่เป็นไปได้ในโค้ด
หมายเหตุ :แม้ว่าจะเป็นไปได้โดยใช้ Exception
ซูเปอร์คลาสใน rescue
บล็อกนี้ท้อแท้มาก
มีคำถามเกี่ยวกับการเพิ่มหรือช่วยเหลือข้อยกเว้นใน Ruby หรือไม่? โปรดอย่าลังเลที่จะแจ้งให้เราทราบที่ @AppSignal แน่นอน เราอยากทราบว่าคุณชอบบทความนี้อย่างไร หรือหากคุณมีหัวข้ออื่นที่ต้องการทราบข้อมูลเพิ่มเติม