ทำไมรูปแบบที่ไม่ถูกต้องในการ `กู้ภัย Exception => e` ใน Ruby


894

Ruby QuickRefของ Ryan Davis พูดว่า (ไม่มีคำอธิบาย):

อย่าช่วยให้มีข้อยกเว้น EVER หรือฉันจะแทงคุณ

ทำไมจะไม่ล่ะ? สิ่งที่ถูกต้องทำคืออะไร?


35
ถ้าอย่างนั้นคุณอาจจะเขียนของคุณเอง? :)
Sergio Tulentsev

65
ฉันอึดอัดมากกับการเรียกร้องให้ใช้ความรุนแรงที่นี่ มันเป็นเพียงการเขียนโปรแกรม
Darth Egregious

1
ดูบทความนี้ใน Ruby Exception พร้อมกับลำดับชั้น Ruby Exception ที่ดี
Atul Khanduri

2
เพราะไรอันเดวิสจะแทงคุณ ดังนั้นเด็ก ๆ ไม่เคยช่วยชีวิตข้อยกเว้น
Mugen

7
@DarthEgregious ฉันไม่สามารถบอกได้จริง ๆ ว่าคุณล้อเล่นหรือไม่ แต่ฉันคิดว่ามันเฮฮา (และเห็นได้ชัดว่าไม่ใช่ภัยคุกคามร้ายแรง) ตอนนี้ทุกครั้งที่ฉันนึกถึงการยกเว้นฉันคิดว่ามันคุ้มค่าที่จะถูกแทงโดยคนที่สุ่มบนอินเทอร์เน็ต
Steve Sether

คำตอบ:


1375

TL; DR : ใช้StandardErrorแทนการจับข้อยกเว้นทั่วไป เมื่อมีการยกข้อยกเว้นดั้งเดิมขึ้นมาใหม่ (เช่นเมื่อการช่วยชีวิตเพื่อบันทึกข้อยกเว้นเท่านั้น) การช่วยชีวิตExceptionอาจไม่เป็นไร


Exceptionเป็นรากของลำดับชั้นยกเว้นทับทิมดังนั้นเมื่อคุณrescue Exceptionคุณช่วยเหลือจากทุกอย่างรวมทั้ง subclasses เช่นSyntaxError, และLoadErrorInterrupt

การช่วยชีวิตInterruptทำให้ผู้ใช้ไม่CTRLCสามารถออกจากโปรแกรมได้

การช่วยชีวิตSignalExceptionป้องกันไม่ให้โปรแกรมตอบสนองต่อสัญญาณอย่างถูกต้อง มันจะไม่สามารถยกเว้นkill -9ได้

การช่วยชีวิตSyntaxErrorหมายความว่าสิ่งevalที่ล้มเหลวจะทำอย่างเงียบ ๆ

สิ่งเหล่านี้สามารถแสดงได้โดยการเรียกใช้โปรแกรมนี้และลองCTRLCหรือkill:

loop do
  begin
    sleep 1
    eval "djsakru3924r9eiuorwju3498 += 5u84fior8u8t4ruyf8ihiure"
  rescue Exception
    puts "I refuse to fail or be stopped!"
  end
end

การช่วยชีวิตExceptionไม่ได้เป็นค่าเริ่มต้น การทำ

begin
  # iceberg!
rescue
  # lifeboats
end

ไม่ช่วยเหลือจากมันบ้างจากException StandardErrorโดยทั่วไปคุณควรระบุสิ่งที่เฉพาะเจาะจงมากกว่าค่าเริ่มต้นStandardErrorแต่การช่วยชีวิตจากขอบเขตให้Exception กว้างขึ้นแทนที่จะ จำกัด ให้แคบลงและอาจมีผลร้ายและทำให้การล่าบั๊กยากมาก


หากคุณมีสถานการณ์ที่คุณต้องการช่วยเหลือStandardErrorและคุณต้องการตัวแปรที่มีข้อยกเว้นคุณสามารถใช้แบบฟอร์มนี้:

begin
  # iceberg!
rescue => e
  # lifeboats
end

ซึ่งเทียบเท่ากับ:

begin
  # iceberg!
rescue StandardError => e
  # lifeboats
end

หนึ่งในสองสามกรณีทั่วไปที่มีสติเพื่อช่วยเหลือExceptionคือเพื่อบันทึก / รายงานซึ่งในกรณีนี้คุณควรยกข้อยกเว้นขึ้นใหม่ทันที:

begin
  # iceberg?
rescue Exception => e
  # do some logging
  raise # not enough lifeboats ;)
end

129
ดังนั้นมันก็เหมือนการจับThrowableใน java
วงล้อประหลาด

53
คำแนะนำนี้เป็นสิ่งที่ดีสำหรับสภาพแวดล้อมทับทิมที่สะอาด แต่น่าเสียดายที่อัญมณีจำนวนหนึ่งได้สร้างข้อยกเว้นที่สืบทอดมาจากข้อยกเว้นโดยตรง สภาพแวดล้อมของเรามี 30 สิ่งเหล่านี้เช่น OpenID :: Server :: EncodingError, OAuth :: InvalidRequest, HTMLTokenizerSample เหล่านี้เป็นข้อยกเว้นที่คุณต้องการอย่างมากในบล็อกช่วยเหลือมาตรฐาน น่าเสียดายที่ไม่มีสิ่งใดในทับทิมป้องกันหรือแม้แต่กีดกันอัญมณีจากการสืบทอดโดยตรงจากข้อยกเว้น - แม้การตั้งชื่อนั้นไม่ได้ใช้งานง่าย
Jonathan Swartz

20
@JonathanSwartz จากนั้นช่วยชีวิตจากคลาสย่อยเฉพาะเหล่านั้นไม่ใช่ข้อยกเว้น เฉพาะเจาะจงมากขึ้นเกือบดีกว่าและชัดเจนกว่าเสมอ
แอนดรูมาร์แชล

22
@JonathanSwartz - ฉันจะบั๊กผู้สร้างอัญมณีเพื่อเปลี่ยนสิ่งที่ยกเว้นของพวกเขาสืบทอด โดยส่วนตัวฉันชอบอัญมณีของฉันที่จะมีข้อยกเว้นทั้งหมดลงมาจาก MyGemException ดังนั้นคุณสามารถช่วยชีวิตได้ถ้าคุณต้องการ
นาธานลอง

12
คุณยังสามารถADAPTER_ERRORS = [::ActiveRecord::StatementInvalid, PGError, Mysql::Error, Mysql2::Error, ::ActiveRecord::JDBCError, SQLite3::Exception]แล้วrescue *ADAPTER_ERRORS => e
j_mcnally

83

จริงกฎ: ห้ามทิ้งข้อยกเว้น ความเที่ยงธรรมของผู้เขียนคำพูดของคุณนั้นเป็นที่น่าสงสัยตามที่เห็นได้จากความจริงที่ลงท้ายด้วย

หรือฉันจะแทงคุณ

แน่นอนให้ระวังว่าสัญญาณ (โดยค่าเริ่มต้น) การโยนข้อยกเว้นและกระบวนการที่ใช้เวลานานจะถูกยกเลิกผ่านสัญญาณดังนั้นการจับยกเว้นและไม่ยุติการยกเว้นสัญญาณจะทำให้โปรแกรมของคุณหยุดยาก ดังนั้นอย่าทำสิ่งนี้:

#! /usr/bin/ruby

while true do
  begin
    line = STDIN.gets
    # heavy processing
  rescue Exception => e
    puts "caught exception #{e}! ohnoes!"
  end
end

ไม่ทำไม่ได้จริงๆ อย่าเรียกใช้เพื่อดูว่าใช้งานได้หรือไม่

อย่างไรก็ตามสมมติว่าคุณมีเซิร์ฟเวอร์ที่มีเธรดและคุณต้องการให้ข้อยกเว้นทั้งหมดไม่ใช่:

  1. ถูกละเว้น (ค่าเริ่มต้น)
  2. หยุดเซิร์ฟเวอร์ (ซึ่งจะเกิดขึ้นถ้าคุณพูดthread.abort_on_exception = true)

จากนั้นเป็นที่ยอมรับอย่างสมบูรณ์ในเธรดการจัดการการเชื่อมต่อ:

begin
  # do stuff
rescue Exception => e
  myLogger.error("uncaught #{e} exception while handling connection: #{e.message}")
    myLogger.error("Stack trace: #{backtrace.map {|l| "  #{l}\n"}.join}")
end

ผลงานด้านบนเป็นรูปแบบของตัวจัดการข้อยกเว้นเริ่มต้นของรูบี้ด้วยข้อดีที่มันไม่ได้ทำให้โปรแกรมของคุณทำงาน Rails ทำสิ่งนี้ในตัวจัดการคำขอ

ข้อยกเว้นสัญญาณถูกยกขึ้นในเธรดหลัก เธรดพื้นหลังจะไม่ได้รับดังนั้นจึงไม่มีประเด็นในการพยายามจับพวกเขาที่นั่น

สิ่งนี้มีประโยชน์อย่างยิ่งในสภาพแวดล้อมการใช้งานจริงซึ่งคุณไม่ต้องการให้โปรแกรมหยุดทำงานเมื่อมีสิ่งผิดปกติเกิดขึ้น จากนั้นคุณสามารถใช้สแต็กดัมพ์ในบันทึกของคุณและเพิ่มลงในโค้ดของคุณเพื่อจัดการกับข้อยกเว้นเฉพาะเพิ่มเติมลงในสายการโทร

โปรดทราบว่ามีสำนวน Ruby อื่นที่มีผลเหมือนกันมาก:

a = do_something rescue "something else"

ในบรรทัดนี้ถ้าdo_somethingยกข้อยกเว้นก็จะถูกจับโดยทับทิมโยนออกไปและได้รับมอบหมายa"something else"

โดยทั่วไปแล้วอย่าทำอย่างนั้นยกเว้นในกรณีพิเศษที่คุณรู้ว่าคุณไม่ต้องกังวล ตัวอย่างหนึ่ง:

debugger rescue nil

debuggerฟังก์ชั่นเป็นวิธีที่ค่อนข้างดีในการตั้งเบรกพอยต์ในรหัสของคุณ แต่ถ้าทำงานนอกดีบักและทางรถไฟมันจะเพิ่มข้อยกเว้น ทีนี้ในทางทฤษฎีคุณไม่ควรปล่อยให้ debug code วางอยู่ในโปรแกรมของคุณ (pff! ไม่มีใครทำอย่างนั้น!) แต่คุณอาจต้องการเก็บมันไว้ชั่วขณะหนึ่งด้วยเหตุผลบางอย่าง แต่ไม่สามารถเรียกใช้ดีบักเกอร์ของคุณได้

บันทึก:

  1. หากคุณเรียกใช้โปรแกรมของบุคคลอื่นที่จับสัญญาณข้อยกเว้นและละเว้นพวกเขา (พูดรหัสด้านบน) จากนั้น:

    • ในลินุกซ์ในเปลือกพิมพ์pgrep rubyหรือps | grep rubyดูสำหรับโปรแกรมการกระทำผิดกฎหมายของ PID kill -9 <PID>และเรียกใช้แล้ว
    • ใน Windows ให้ใช้ตัวจัดการงาน ( CTRL- SHIFT- ESC) ไปที่แท็บ "กระบวนการ" ค้นหากระบวนการของคุณคลิกขวาและเลือก "สิ้นสุดกระบวนการ"
  2. หากคุณกำลังทำงานกับโปรแกรมของคนอื่นซึ่งไม่ว่าด้วยเหตุผลใดก็ตามที่มีการใช้บล็อกที่ไม่ใช้ข้อยกเว้นเหล่านี้ให้วางที่ด้านบนสุดของการฉีดยาเป็นวิธีแก้ปัญหาหนึ่งที่เป็นไปได้:

    %W/INT QUIT TERM/.each { |sig| trap sig,"SYSTEM_DEFAULT" }

    นี้ทำให้โปรแกรมที่จะตอบสนองต่อสัญญาณการเลิกจ้างตามปกติโดยทันทียุติผ่านไสข้อยกเว้น ที่ไม่มีการทำความสะอาด ดังนั้นอาจทำให้ข้อมูลสูญหายหรือคล้ายกัน ระวัง!

  3. หากคุณต้องการทำสิ่งนี้:

    begin
      do_something
    rescue Exception => e
      critical_cleanup
      raise
    end

    คุณสามารถทำสิ่งนี้ได้จริง:

    begin
      do_something
    ensure
      critical_cleanup
    end

    ในกรณีที่สองcritical cleanupจะถูกเรียกทุกครั้งไม่ว่าจะมีข้อยกเว้นหรือไม่


21
ขออภัยนี่ผิด เซิร์ฟเวอร์ไม่ควรช่วยเหลือ Exception และไม่ทำอะไรนอกจากเข้าสู่ระบบ ที่จะทำให้ไม่สามารถยกเว้นkill -9ได้
จอห์น

8
ตัวอย่างของคุณในหมายเหตุ 3 ไม่เท่าเทียมกันและensureจะทำงานโดยไม่คำนึงว่ามีข้อยกเว้นเกิดขึ้นหรือไม่ในขณะที่rescueจะทำงานเฉพาะในกรณีที่มีข้อยกเว้นเกิดขึ้น
Andrew Marshall

1
พวกเขาไม่ได้ / / เทียบเท่า แต่ฉันไม่สามารถหาวิธีที่จะแสดงความเท่าเทียมในวิธีที่ไม่น่าเกลียด
Michael Slade

3
เพียงเพิ่มการเรียก critical_cleanup อีกครั้งหลังจากบล็อกเริ่มต้น / กู้ภัยในตัวอย่างแรก ฉันไม่เห็นด้วยกับรหัสที่งดงามที่สุด แต่เห็นได้ชัดว่าตัวอย่างที่สองคือวิธีที่สง่างามในการทำเช่นนั้นดังนั้นความไม่ประณีตเล็กน้อยเป็นเพียงส่วนหนึ่งของตัวอย่าง
gtd

3
"อย่าเรียกใช้เพื่อดูว่าใช้งานได้หรือไม่" ดูเหมือนจะเป็นคำแนะนำที่ไม่ดีสำหรับการเข้ารหัส ... ในทางกลับกันฉันแนะนำให้คุณเรียกใช้เพื่อดูว่ามันล้มเหลวและเข้าใจด้วยตัวคุณเองว่าล้มเหลวอย่างไรแทนที่จะเชื่อคนอื่นโดยสุ่ม คำตอบที่ดีอยู่แล้ว :)
huelbois

69

TL; DR

อย่าrescue Exception => e(ยกเว้นการเพิ่มข้อยกเว้นใหม่) - หรือคุณอาจขับรถออกจากสะพาน


สมมติว่าคุณอยู่ในรถ (ใช้ทับทิม) คุณเพิ่งติดตั้งพวงมาลัยใหม่พร้อมระบบอัปเกรดแบบ over-the-air (ซึ่งใช้eval) แต่คุณไม่รู้ว่าโปรแกรมเมอร์คนใดคนหนึ่งสับสนกับไวยากรณ์

คุณอยู่บนสะพานและตระหนักว่าคุณกำลังมุ่งหน้าไปยังทางแยกดังนั้นคุณเลี้ยวซ้าย

def turn_left
  self.turn left:
end

โอ๊ะ! นั่นอาจเป็นสิ่งที่ไม่ดี ™โชคดีที่ทับทิมยกตัวSyntaxErrorขึ้น

รถควรหยุดทันที - ใช่ไหม?

Nope

begin
  #...
  eval self.steering_wheel
  #...
rescue Exception => e
  self.beep
  self.log "Caught #{e}.", :warn
  self.log "Logged Error - Continuing Process.", :info
end

เสียงบี๊บ

คำเตือน: Caught SyntaxError Exception

ข้อมูล: ข้อผิดพลาดการบันทึก - กระบวนการต่อเนื่อง

คุณสังเกตเห็นบางสิ่งบางอย่างที่ไม่ถูกต้องและคุณได้ชัยชนะในการแบ่งฉุกเฉิน ( ^C: Interrupt)

เสียงบี๊บ

คำเตือน: การดักจับการขัดจังหวะ

ข้อมูล: ข้อผิดพลาดการบันทึก - กระบวนการต่อเนื่อง

ใช่ - นั่นไม่ได้ช่วยอะไรมาก คุณสวยใกล้กับทางรถไฟเพื่อให้คุณใส่รถในสวนสาธารณะ ( killไอเอ็นจี: SignalException)

เสียงบี๊บ

คำเตือน: Caught SignalException Exception

ข้อมูล: ข้อผิดพลาดการบันทึก - กระบวนการต่อเนื่อง

ในวินาทีสุดท้ายคุณดึงกุญแจ ( kill -9) และรถหยุดคุณกระแทกไปที่พวงมาลัย (ถุงลมนิรภัยไม่สามารถพองขึ้นได้เพราะคุณไม่ได้หยุดโปรแกรมอย่างสง่างาม - คุณยกเลิกมัน) และคอมพิวเตอร์ ที่ด้านหลังของรถของคุณกระแทกเข้ากับที่นั่งด้านหน้ามัน กระป๋องโค้กครึ่งกระป๋องหกล้นเหนือกระดาษ ร้านขายของชำด้านหลังถูกบดขยี้และส่วนใหญ่จะอยู่ในไข่แดงและนม รถต้องการการซ่อมแซมและทำความสะอาดที่รุนแรง (การสูญเสียข้อมูล)

หวังว่าคุณจะมีประกัน (สำรอง) โอ้ใช่ - เพราะถุงลมนิรภัยไม่พองตัวคุณอาจบาดเจ็บ (โดนไล่ออก ฯลฯ )


แต่เดี๋ยวก่อน! มีมากกว่าเหตุผลที่คุณอาจต้องการใช้rescue Exception => e!

สมมติว่าคุณเป็นรถคันนั้นและคุณต้องการตรวจสอบให้แน่ใจว่าถุงลมนิรภัยพองตัวหากรถเกินแรงหยุดที่ปลอดภัย

 begin 
    # do driving stuff
 rescue Exception => e
    self.airbags.inflate if self.exceeding_safe_stopping_momentum?
    raise
 end

ต่อไปนี้เป็นข้อยกเว้น: คุณสามารถจับเท่านั้นถ้าคุณเพิ่มอีกข้อยกเว้นException ดังนั้นกฎที่ดีกว่าคือไม่เคยกลืนกินExceptionและยกข้อผิดพลาดขึ้นมาใหม่

แต่การเพิ่มการช่วยเหลือนั้นทั้งง่ายที่จะลืมในภาษาเช่น Ruby และใส่คำสั่งการช่วยเหลือทันทีก่อนที่จะหยิบยกปัญหาขึ้นมาใหม่ และคุณไม่ต้องการที่จะลืมraiseคำสั่ง และถ้าคุณทำเช่นนั้นโชคดีที่พยายามค้นหาข้อผิดพลาดนั้น

โชคดีที่ทับทิมยอดเยี่ยมคุณสามารถใช้ensureคำหลักซึ่งทำให้แน่ใจว่ารหัสทำงาน ensureคำหลักที่จะเรียกใช้รหัสไม่ว่าสิ่งที่ - ถ้ายกเว้นจะโยนถ้าใครไม่ได้เป็นข้อยกเว้นเพียงอย่างเดียวถ้าโลกปลาย (หรือเหตุการณ์ที่ไม่น่าที่อื่น ๆ )

 begin 
    # do driving stuff
 ensure
    self.airbags.inflate if self.exceeding_safe_stopping_momentum?
 end

บูม! และรหัสนั้นควรจะทำงานต่อไป เหตุผลเดียวที่คุณควรใช้rescue Exception => eคือถ้าคุณต้องการเข้าถึงข้อยกเว้นหรือหากคุณต้องการให้โค้ดทำงานบนข้อยกเว้น และอย่าลืมเพิ่มข้อผิดพลาดอีกครั้ง ทุกเวลา.

หมายเหตุ: ตามที่ @Niall ชี้ให้เห็นว่าทำงานอยู่เสมอ นี่เป็นสิ่งที่ดีเพราะบางครั้งโปรแกรมของคุณอาจโกหกคุณและไม่ส่งข้อยกเว้นแม้ว่าจะเกิดปัญหาก็ตาม ด้วยภารกิจที่สำคัญเช่นถุงลมนิรภัยที่พองตัวคุณต้องทำให้แน่ใจว่ามันจะเกิดขึ้นไม่ว่าจะเกิดอะไรขึ้น ด้วยเหตุนี้การตรวจสอบทุกครั้งที่รถหยุดไม่ว่าจะเกิดข้อยกเว้นหรือไม่ก็ตามเป็นความคิดที่ดี ถึงแม้ว่าถุงลมนิรภัยที่พองตัวจะเป็นงานที่ผิดปกติในบริบทการเขียนโปรแกรมส่วนใหญ่ แต่นี่เป็นเรื่องธรรมดาสำหรับงานล้างข้อมูลส่วนใหญ่


12
ฮ่า ๆ ๆ ๆ! นี่คือคำตอบที่ดี ฉันตกใจที่ไม่มีใครแสดงความคิดเห็น คุณให้สถานการณ์ที่ชัดเจนซึ่งทำให้เข้าใจได้ง่าย ไชโย! :-)
James Milani

@JamesMilani ขอขอบคุณ!
Ben Aubin

3
+ 💯สำหรับคำตอบนี้ หวังว่าฉันจะสามารถโหวตมากกว่าหนึ่งครั้ง! 😂
engineerDave

1
สนุกกับคำตอบของคุณ!
Atul Vaibhav

3
คำตอบนี้มา 4 ปีหลังจากคำตอบที่ยอมรับและเข้าใจได้อย่างสมบูรณ์แบบและอธิบายอีกครั้งด้วยสถานการณ์ที่ไร้สาระที่ออกแบบมาให้น่าขบขันมากกว่าความเป็นจริง ขออภัยที่จะเป็น buzzkill แต่นี่ไม่ใช่ reddit - มันสำคัญสำหรับคำตอบที่รวบรัดและถูกต้องกว่าตลก นอกจากนี้ส่วนที่เกี่ยวกับensureทางเลือกที่rescue Exceptionจะทำให้เข้าใจผิด - ตัวอย่างบ่งบอกว่าพวกเขาเทียบเท่า แต่ตามที่ระบุไว้ensureจะเกิดขึ้นไม่ว่าจะมีข้อยกเว้นหรือไม่ดังนั้นตอนนี้ถุงลมนิรภัยของคุณจะพองเพราะคุณไป 5 ไมล์ต่อชั่วโมง
Niall

47

เพราะสิ่งนี้จับข้อยกเว้นทั้งหมด ก็ไม่น่าที่โปรแกรมของคุณสามารถกู้คืนจากใด ๆของพวกเขา

คุณควรจัดการข้อยกเว้นเฉพาะที่คุณรู้วิธีการกู้คืนจาก หากคุณไม่คาดว่าจะมีข้อยกเว้นบางประเภทอย่าจัดการมันพังเสียงดัง (เขียนรายละเอียดลงในบันทึก) จากนั้นจึงวิเคราะห์บันทึกและรหัสแก้ไข

การกลืนข้อยกเว้นไม่ดีอย่าทำเช่นนี้


10

นั่นเป็นกรณีเฉพาะของกฎที่คุณไม่ควรจับใด ๆยกเว้นคุณไม่ทราบวิธีการจัดการ หากคุณไม่ทราบวิธีจัดการกับมันจะดีกว่าเสมอที่จะให้ส่วนอื่น ๆ ของระบบจับและจัดการได้


0

ฉันเพิ่งอ่านโพสต์บล็อกที่ยอดเยี่ยมเกี่ยวกับมันที่honeybadger.io :

ข้อยกเว้นของรูบี้กับ StandardError: ความแตกต่างคืออะไร?

ทำไมคุณไม่ควรช่วยเหลือการยกเว้น

ปัญหาเกี่ยวกับการช่วยเหลือ Exception คือว่ามันช่วยจริงทุกข้อยกเว้นที่สืบทอดจาก Exception นั่นคือ .... พวกเขาทั้งหมด!

นั่นเป็นปัญหาเพราะมีข้อยกเว้นบางอย่างที่ทับทิมใช้ภายใน พวกเขาไม่มีอะไรเกี่ยวข้องกับแอพของคุณและการกลืนพวกมันจะทำให้สิ่งเลวร้ายเกิดขึ้น

นี่คือบางส่วนที่มีขนาดใหญ่:

  • SignalException :: Interrupt - หากคุณช่วยเหลือสิ่งนี้คุณจะไม่สามารถออกจากแอพได้โดยกดปุ่ม control-c

  • ScriptError :: SyntaxError - ข้อผิดพลาดทางไวยากรณ์การกลืนหมายความว่าสิ่งต่าง ๆ ที่ทำให้ ("ลืมอะไรบางอย่าง") จะล้มเหลวอย่างเงียบ ๆ

  • NoMemoryError - อยากรู้ว่าจะเกิดอะไรขึ้นเมื่อโปรแกรมของคุณทำงานต่อไปหลังจากที่ใช้แรมหมดแล้ว? ฉันก็ไม่เหมือนกัน.

begin
  do_something()
rescue Exception => e
  # Don't do this. This will swallow every single exception. Nothing gets past it. 
end

ฉันเดาว่าคุณไม่ต้องการกลืนข้อยกเว้นระดับระบบใด ๆ เหล่านี้ คุณต้องการจับข้อผิดพลาดระดับแอปพลิเคชันทั้งหมดของคุณเท่านั้น ข้อยกเว้นทำให้รหัสของคุณ

โชคดีที่มีวิธีง่ายๆในการทำสิ่งนี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.