Exception คือโครงสร้างข้อมูลพิเศษที่เก็บข้อมูลเกี่ยวกับ exceptional condition ที่เกิดใน application Exceptions เป็นสัญญาณส่งเมื่อโปรแกรมไม่สามารถทำงานต่อได้เพราะไม่รู้จักจัดการสถานการณ์เฉพาะนั้น ใน Ruby เราเรียกการส่งสัญญาณเช่นนี้ว่า raising exception
raise 'this is an exception'
puts "This message won't be printed."
วิธีเร็วที่สุดเห็น exception ในการทำงานคือ raise เอง ด้วย raise method พร้อม message Ruby จะสร้าง RuntimeError พร้อมข้อความที่ส่งผ่านเป็น description มันยังเพิ่ม stack trace ชี้ไปที่จุดที่ raise exception ในโค้ดของคุณ
$ ruby raise.rb
raise.rb:1:in `': this is an exception (RuntimeError)
เมื่อรัน script ข้างต้น คุณจะสังเกตว่า ตามสัญญา message หลัง raise exception ไม่ถูกพิมพ์ นั่นเพราะ unhandled exceptions หยุดการ execute โปรแกรมโดยทำให้ crash เพื่อให้แน่ใจว่า application ไม่ทำงานต่อหลังจาก fail ในการทำหน้าที่หนึ่ง
ประเภท Exceptions ที่ต่างกัน
ภายใน Ruby raise exceptions เมื่อสิ่งผิดพลาด ตัวอย่าง คุณจะได้ exception เมื่อพยายามหารตัวเลขด้วยศูนย์
irb(main):001:0> 42/0
ZeroDivisionError: divided by 0
from (irb):1:in `/'
from (irb):1
from /Users/jeff/.asdf/installs/ruby/2.3.0/bin/irb:11:in `'
ในกรณีนี้ exception type คือ ZeroDivisionError แทน RuntimeError ที่เห็นก่อน มี exception types หลายสิบประเภทสร้าง exception hierarchy ของ Ruby และ raise ในสถานการณ์ต่างกัน
RuntimeError เป็น exception class แบบ generic กว่ามีตัวอย่าง specific มากกว่า NoMethodError raise เมื่อพยายามเรียก method ที่ไม่มีอยู่ และ ArgumentError บ่งบอกว่า arguments ผิดส่งไป method ที่มีอยู่
Rescue Exceptions
แอปพลิเคชันส่วนใหญ่ต้องการความสามารถ recover จาก exceptions ใน web application error อาจเกิดเมื่อ user ส่งข้อมูลผิดใน form ควรแสดง error message ให้ user แทนที่จะ crash web server ทั้งหมด
ในกรณีแบบนั้น exception อาจ raise แต่จะถูก rescue โดย web server ก่อนถึง top of call stack ป้องกัน exception ไม่ให้ crash application
begin
raise 'this is an exception'
rescue RuntimeError => exception
puts "Exception rescued: #{exception.inspect}"
# => "Exception rescued: #"
end
puts "This message *will* be printed."
ด้วยการ wrap ตัวอย่างก่อนหน้าใน begin/rescue block exception จะไม่ raise และไม่ crash app แทน rescue-block จะ execute พิมพ์ message อธิบายว่า exception ถูก阻止 ในกรณีนี้ เพราะป้องกัน app ไม่ crash message สุดท้าย จะ ถูกพิมพ์
ตัวอย่างนี้ rescue RuntimeErrors เฉพาะ ดังนั้น error อื่นจะไม่ถูกจับ การระบุเฉพาะ errors ที่ rescued สะดวก เพราะทำให้ทำสิ่งต่างกันเมื่อ errors ต่างๆ เกิดขึ้น สำคัญคือ ต้องแน่ใจว่าไม่ rescue exceptions มากเกินไป
สำหรับ primer ลึกขึ้นเกี่ยว exception handling และ tips เกี่ยวการ rescue exceptions อย่างถูกต้อง ดู exceptions primer บน Ruby Magic ของเราได้
มีคำถามเกี่ยวการ raise หรือ catch exceptions ใน Ruby? อย่าลังเลติดต่อเราที่ @AppSignal เรายินดีรู้ความคิดเห็นว่าชอบบทความนี้หรือไม่ หรือมีหัวข้ออื่นอยากรู้เพิ่มเติม