วิธีการออกแบบข้อยกเว้น


11

ฉันกำลังดิ้นรนกับคำถามง่าย ๆ :

ตอนนี้ฉันกำลังทำงานกับแอปพลิเคชันเซิร์ฟเวอร์และฉันต้องคิดค้นลำดับชั้นสำหรับข้อยกเว้น (มีข้อยกเว้นบางอย่างอยู่แล้ว แต่จำเป็นต้องใช้กรอบงานทั่วไป) ฉันจะเริ่มทำสิ่งนี้ได้อย่างไร

ฉันกำลังคิดว่าจะทำตามกลยุทธ์นี้:

1) เกิดอะไรขึ้น?

  • มีบางสิ่งถามซึ่งไม่ได้รับอนุญาต
  • มีการถามอะไรบางอย่างอนุญาต แต่ไม่ทำงานเนื่องจากพารามิเตอร์ผิด
  • มีการถามบางสิ่งอนุญาต แต่ไม่ทำงานเนื่องจากข้อผิดพลาดภายใน

2) ใครเป็นผู้เปิดตัวคำขอ?

  • แอปพลิเคชันไคลเอนต์
  • แอปพลิเคชันเซิร์ฟเวอร์อื่น

3) การส่งข้อความ: เนื่องจากเรากำลังติดต่อกับแอปพลิเคชันเซิร์ฟเวอร์ทุกอย่างเกี่ยวกับการรับและส่งข้อความ แล้วถ้าเกิดว่าการส่งข้อความผิดพลาดล่ะ

ดังนั้นเราอาจได้รับประเภทข้อยกเว้นดังต่อไปนี้:

  • ServerNotAllowedException
  • ClientNotAllowedException
  • ServerParameterException
  • ClientParameterException
  • InternalException (ในกรณีที่เซิร์ฟเวอร์ไม่รู้ว่าคำขอมาจากไหน)
    • ServerInternalException
    • ClientInternalException
  • MessageHandlingException

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

ขอบคุณล่วงหน้า


5
คุณไม่ได้พูดถึงสิ่งที่คุณต้องการให้บรรลุด้วยลำดับชั้นของคลาสข้อยกเว้น (ซึ่งไม่ชัดเจนเลย) การบันทึกที่มีความหมาย? ทำให้ลูกค้าสามารถตอบสนองต่อข้อยกเว้นที่แตกต่างกันได้อย่างสมเหตุสมผล? หรืออะไร?
Ralf Kleberhoff

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

1
จากความเกี่ยวข้องฉันเดาว่าsoftwareengineering.stackexchange.com/questions/278949//
มาร์ตินบา

1
ฉันไม่เคยเข้าใจความต้องการที่จะใช้ข้อยกเว้นประเภทต่างๆมากมาย โดยทั่วไปแล้วสำหรับcatchบล็อกส่วนใหญ่ที่ฉันใช้ฉันไม่ได้ใช้ข้อยกเว้นมากไปกว่าข้อความแสดงข้อผิดพลาดที่มีอยู่ ฉันไม่ได้มีอะไรที่แตกต่างกันจริง ๆ ที่ฉันสามารถทำได้สำหรับข้อยกเว้นที่เกี่ยวข้องกับการไม่สามารถอ่านไฟล์เป็นหนึ่งล้มเหลวในการจัดสรรหน่วยความจำในระหว่างขั้นตอนการอ่านดังนั้นฉันจึงมักจะจับstd::exceptionและรายงานข้อความแสดงข้อผิดพลาด มัน"Failed to open file: %s", ex.what()ไปยังกองบัฟเฟอร์ก่อนที่จะพิมพ์

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

คำตอบ:


5

ข้อสังเกตทั่วไป

(ความเห็นเล็กน้อย)

ฉันมักจะไม่ไปเพื่อลำดับชั้นข้อยกเว้นโดยละเอียด

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

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

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

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

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

ลำดับชั้นของคุณ

ใครเป็นผู้เปิดตัวคำขอ? ฉันไม่คิดว่าคุณจะต้องการข้อมูลที่เปิดตัวคำขอ ฉันไม่สามารถจินตนาการได้ว่าคุณจะรู้ได้อย่างไรว่าในส่วนลึกของการโทร

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

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

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


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

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

2

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

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

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

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

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

  • ที่เกี่ยวข้องกับการจุดก่อนหน้านี้จำไว้ว่าเพียงเพราะคุณใช้ข้อยกเว้นเพื่อตอบสนองต่อข้อผิดพลาดที่ไม่ได้หมายความว่าคุณต้องใช้เพียงข้อยกเว้นสำหรับรัฐข้อผิดพลาด โปรดทราบว่าการโยนข้อยกเว้นมีราคาแพงและค่าใช้จ่ายในการปฏิบัติงานอาจแตกต่างกันไปในแต่ละภาษา สำหรับบางภาษาค่าใช้จ่ายจะสูงกว่าทั้งนี้ขึ้นอยู่กับความลึกของ call stack ดังนั้นหากเกิดข้อผิดพลาดใน call stack ให้ตรวจสอบว่าคุณไม่สามารถใช้ประเภทดั้งเดิมอย่างง่าย (รหัสข้อผิดพลาดจำนวนเต็มหรือแฟล็กบูลีน) เกิดข้อผิดพลาดสำรองสแต็กเพื่อให้สามารถโยนเข้าใกล้การเรียกของผู้โทรได้มากขึ้น

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

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


2
ยกเว้นกระสุนนัดที่สองของคุณ (ประมาณค่าใช้จ่ายของข้อยกเว้น) คำตอบนั้นดี สัญลักษณ์แสดงหัวข้อย่อยเกี่ยวกับค่าใช้จ่ายของข้อยกเว้นนั้นทำให้เข้าใจผิดเพราะในวิธีการทั่วไปทั้งหมดของการใช้ข้อยกเว้นในระดับต่ำค่าใช้จ่ายในการขว้างข้อยกเว้นนั้นขึ้นอยู่กับความลึกของสแต็กการโทร วิธีการรายงานข้อผิดพลาดทางเลือกอาจดีกว่าถ้าคุณรู้ว่าข้อผิดพลาดจะได้รับการจัดการโดยผู้เรียกทันที แต่จะไม่รับฟังก์ชั่นบางอย่างจากสแต็กการโทรก่อนโยนข้อยกเว้น
Bart van Ingen Schenau

@BartvanIngenSchenau: ฉันพยายามไม่ผูกมันกับภาษาใดภาษาหนึ่ง ในบางภาษา ( Java เช่น ) ความลึกของ call stack จะส่งผลต่อค่าใช้จ่ายในการสร้างอินสแตนซ์ ฉันจะแก้ไขเพื่อสะท้อนว่ามันไม่ได้ถูกตัดและแห้ง
Mark Benningfield

0

ฉันจะแนะนำให้คุณก่อนอื่นสร้างExceptionชั้นฐานสำหรับข้อยกเว้นการตรวจสอบทั้งหมดซึ่งอาจถูกโยนโดยใบสมัครของคุณ หากใบสมัครของคุณถูกเรียกใช้DuckTypeให้สร้างDuckTypeExceptionคลาสพื้นฐาน

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

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

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

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

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

ตามกฎทั่วไปแล้วความพยายามในการจับของคุณควรจะเพิ่มมากขึ้นเมื่อคุณเลื่อน callstack ของผู้โทรเพื่อจัดการข้อยกเว้นและอีกครั้งในคอนโทรลเลอร์หลักของคุณคุณจะไม่จัดการDatabaseConnectionExceptionแต่ง่ายDuckTypeExceptionกว่าข้อยกเว้นที่คุณเลือกทั้งหมดมา


2
โปรดทราบว่าคำถามถูกติดแท็ก "C ++"
Martin Ba

0

พยายามทำให้ง่ายขึ้น

สิ่งแรกที่จะช่วยให้คุณคิดในกลยุทธ์อื่นคือจับข้อยกเว้นจำนวนมากคล้ายกับการใช้ข้อยกเว้นตรวจสอบจาก Java (ขออภัยฉันไม่ใช่นักพัฒนา C ++) สิ่งนี้ไม่ดีสำหรับหลาย ๆ เหตุผลดังนั้นฉันมักจะพยายามไม่ใช้มันและกลยุทธ์การยกเว้นลำดับชั้นของคุณจำฉันได้หลายอย่าง

ดังนั้นฉันขอแนะนำกลยุทธ์อื่นและยืดหยุ่น: ใช้ข้อยกเว้นที่ไม่ จำกัดและข้อผิดพลาดของรหัส

ตัวอย่างดูรหัส Java นี้:

public class SystemErrorCode implements ErrorCode {

    INVALID_NAME(101),
    ORDER_NOT_FOUND(102),
    PARAMETER_NOT_FOUND(103),
    VALUE_TOO_SHORT(104);

    private final int number;

    private ErrorCode(int number) {
        this.number = number;
    }

    @Override
    public int getNumber() {
        return number;
    }
}

และข้อยกเว้นเฉพาะของคุณ:

public class SystemException extends RuntimeException {

    private ErrorCode errorCode;

    public SystemException(ErrorCode errorCode) {
        this.errorCode = errorCode;
    }

}

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

ตามที่คุณต้องการแยกข้อยกเว้นต่าง ๆ ระหว่างแอปพลิเคชัน "ไคลเอนต์" และ "เซิร์ฟเวอร์อื่น" คุณสามารถมีคลาสรหัสข้อผิดพลาดหลายคลาสที่ใช้อินเตอร์เฟส ErrorCode


2
โปรดทราบว่าคำถามถูกติดแท็ก "C ++"
Sjoerd

ฉันแก้ไขเพื่อปรับความคิด
Dherik

0

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

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

ข้อยกเว้นจะต้องอยู่ในบริบทของฟังก์ชันที่เรียกใช้ ตัวอย่างเช่นฟังก์ชั่นที่แก้สมการกำลังสอง มันจะต้องจัดการกับข้อยกเว้นสองประการ: Division_by_zero และ square_root_of_negative_number แต่ข้อยกเว้นเหล่านี้ไม่สมเหตุสมผลสำหรับฟังก์ชันที่เรียกว่าตัวแก้สมการกำลังสอง พวกเขาเกิดขึ้นเพราะวิธีการที่ใช้ในการแก้สมการและเพียงแค่ rethrowing พวกเขา exposes ภายในและแบ่งการใส่ แต่จะต้องถูกแบ่งออกเป็น Division_by_zero แทน not_quadratic และ square_root_of_negative_number และ no_real_roots

ไม่จำเป็นต้องมีลำดับชั้นของข้อยกเว้น Enum ของข้อยกเว้น (ซึ่งระบุไว้) ที่ส่งออกมาโดยฟังก์ชันนั้นเพียงพอเพราะฟังก์ชันการเรียกต้องจัดการกับพวกเขา การอนุญาตให้พวกเขาประมวลผลทรีการเรียกใช้เป็น goto นอกบริบท (ไม่ จำกัด )

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