Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

เชี่ยวชาญ Ruby Error Handling: ใช้ begin และ rescue จัดการ Exceptions

ปัญหา आमใน Ruby คือ Error Messages — ใน Technical Terms เรียกว่า "Exceptions"

Exceptions อาจ คาดการณ์ได้ (Expected) เช่น File ที่มีบ้างคราวหาย, API Available ชั่วคราว — หรือ ไม่คาดคิด (Unexpected)

วันนี้เรียนจัดการ Expected Errors

ทำยังไง? มารู้จัก "begin" และ "rescue" ใน Ruby — 2 Keywords สำคัญ Handle Error Conditions

ทำงานยังไง? ก่อนเข้าใจว่า Ruby Programs อาจ Trigger Error หลายจุดระหว่างรัน

ตัวอย่าง:

  • อ่านไฟล์ไม่มีอยู่
  • หารเลขด้วยศูนย์
  • Web Server SSL Certificate Expired

ตอน Error เกิดขึ้น... Ruby ไม่ Crash ทันที! — ได้ โอกาส Recover จาก Error เรียกว่า "Exception Handling"

Ruby ให้ Keywords Implement Error Recovery: begin & rescue — มาเรียนรู้!

วิธี Handle Ruby Exceptions

Wrap โค้ดที่อาจ Raise Exception ด้วย begin / rescue Block

ทำงานแบบนี้...

Section แรก (begin) = โค้ดที่จะรัน และอาจ Raise Exception

ตัวอย่าง:

begin
  IO.sysopen('/dev/null')
rescue
  # ...
end

พยายามเปิดไฟล์ sysopen — Exception ถ้าเปิดไม่ได้ — เวลาเหมาะสำหรับ rescue!

用 rescue บอกว่าตอน Exception เกิดขึ้น อยากให้เกิดอะไรขึ้น — Failure Mode อยู่ใต้ Control

ตัวอย่าง:

begin
  IO.sysopen('/dev/null')
rescue
  puts "Can't open IO device."
end

อยาก Log Error และอาจให้ Default Value — อย่า. Ignore. Errors.

Rescuing Multiple Exceptions

rescue รับ Optional Argument — คือ Exception Class ที่อยาก Rescue — ขึ้นอยู่กับ Code ที่รัน

สำหรับ IO:

  • Errno::ENOENT = File ไม่มี
  • Errno::EACCES = Permission Error

จุดดี: Handle Multiple Exceptions ใน Block เดียวได้

แบบนี้:

begin
  IO.sysopen('/dev/null')
rescue Errno::ENOENT
  puts "File not found."
rescue Errno::EACCES
  puts "Insufficient permissions, not allowed to open file."
end

อยาก Same Action สำหรับ Multiple Exceptions — ทำได้:

begin
  IO.sysopen('/dev/null')
rescue Errno::ENOENT, Errno::EACCES
  puts "There was an error opening the file."
end

เรียนต่อ!

Rescue Exceptions ภายใน Blocks และ Methods

ไม่บังคับ begin เสมอ — มี Cases ปล่อยได้

ที่ไหน? ภายใน Methods และ Blocks

ตัวอย่าง Method:

def get_null_device
  IO.sysopen('/dev/null')
rescue Errno::ENOENT
  puts "Can't open IO device."
end

Method Definition เองทำหน้าที่ begin — ปล่อยได้

Blocks ก็ได้:

["a.txt", "b.txt", "c.txt"].map do |f|
  IO.sysopen(f)
rescue Errno::ENOENT
  puts "Can't open IO device: #{f}."
end

อีก 1 วิธี 用 rescue โดยไม่ต้อง begin — มาดู

เข้าใจ Inline Rescue และทำไมถึงอันตราย

用 rescue Inline ได้ — บางกรณีหายาก Form นี้มีประโยชน์

ตัวอย่าง:

["a.txt", "b.txt", "c.txt"].select { |f| File.open(f) rescue nil }.map(&:size)

เปิดเฉพาะไฟล์ที่มีอยู่ ข้ามที่ไม่มี — ได้ Size ของไฟล์ที่มี — ไม่ Raise Exceptions

ทำไมทำ? โค้ดอยู่บรรทัดเดียว — นั่นแหละ

แตมี "Hidden Danger" — เพราะ Rescue ทุก Exceptions ที่สืบมาจาก StandardError (ส่วนใหญ่)

ทำไม NOT Good? ควร Handle Specific Exceptions แทน Broad Selection — หลีกเลี่ยงซ่อน Errors จากตัวเอง! Hidden Errors นำไปสู่ Strange Behavior และ Hard-to-debug Issues

Summary (สรุป)

คุณเรียนรู้ Errors ใน Ruby, Basic Exception Handling, และ Keywords rescue / begin

Share บทความถ้าHelpful 🙂 — ขอบคุณที่อ่านครับ!