ความละเอียดของข้อยกเว้น


9

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

  • BadRequestException
  • AuthenticationFailureException
  • ProductNotFoundException

แต่ละรายการเหล่านี้สร้างขึ้นตามรหัสข้อผิดพลาดที่ส่งคืนจาก API

การติดตามข้อดีของข้อยกเว้นนี้ดูเหมือนว่าเป็นไปไม่ได้สำหรับ Java อย่างไรก็ตามความคิดเห็นของเพื่อนฉันไม่ใช่เรื่องแปลก

มีวิธีที่ต้องการในแง่ของความสามารถในการอ่านโค้ดและการใช้งาน API หรือว่ามันเป็นเรื่องที่ชอบ?


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

@marstato นั่นยุติธรรม ฉันเดาว่าฉันกำลังมองหาเหตุผลในตำแหน่งของฉัน ฉันอยากจะทำในสิ่งที่ผู้คนคาดหวังในห้องสมุดที่ฉันเขียนแทนที่จะทำตามคำแนะนำว่ามันทำให้การใช้ของฉันง่ายขึ้นใช่ไหม

ฉันเห็นด้วยอย่างยิ่ง ฉันมีคลาสข้อยกเว้นที่ละเอียดมากเช่นกัน นอกจากนี้คุณสามารถกำหนดabstractและยกเว้นคลาสคลาสทั่วไปด้วยเมธอด getter จากนั้นทำให้กลุ่มย่อยขยายกลุ่มทั่วไป AuthenticationFaliureException extends ClientErrorExceptionเช่น ด้วยวิธีนี้ผู้ใช้ทุกคนสามารถเลือกได้ว่าต้องการจัดการกับข้อยกเว้นอย่างไร มันใช้งานได้มากกว่าแน่นอน อย่างไรก็ตามเมื่อเขียนแอปพลิเคชัน (แทนที่จะเป็นห้องสมุด) มันเป็นสถานการณ์ที่แตกต่างกันของ IMHO ในกรณีนี้ฉันจะไม่ทำให้ข้อยกเว้นละเอียดเกินกว่าที่คุณต้องการเพื่อความเรียบง่าย
marstato

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

คำตอบ:


15

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

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

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

ไม่มีวิธีแก้ปัญหาเดียวที่เหมาะกับทุกสิ่งนี้ไม่มี "วิธีปฏิบัติที่ดีที่สุด" ที่คุณสามารถนำไปใช้ได้ทุกที่ทุกเวลา คำตอบสำหรับคำถามนี้ขึ้นอยู่กับซอฟต์แวร์หรือส่วนประกอบที่คุณออกแบบ:

  • แอปพลิเคชั่นบางตัวที่คุณหรือทีมมีฐานรหัสทั้งหมดภายใต้การควบคุมของคุณ

  • หรือส่วนประกอบที่นำกลับมาใช้ใหม่บางอย่างสำหรับบุคคลที่สามซึ่งคุณไม่รู้จักผู้ที่โทรมาทั้งหมด?

  • แอปพลิเคชั่นเซิร์ฟเวอร์ที่ใช้งานมานานซึ่งข้อผิดพลาดประเภทต่าง ๆ ไม่ควรทำลายทั้งระบบในทันทีและอาจต้องการการแก้ไขข้อผิดพลาดประเภทต่าง ๆ

  • กระบวนการแอปพลิเคชันที่มีอายุสั้นซึ่งเพียงพอในกรณีที่เกิดข้อผิดพลาดในการแสดงข้อความแสดงข้อผิดพลาดกับผู้ใช้และจากนั้นรีสตาร์ทกระบวนการ

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


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

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

1

คำตอบนั้นขึ้นอยู่กับระดับการรายงานข้อผิดพลาดที่เรากำลังพูดถึง

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

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

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

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

ครั้งแรกมันจะล้างคอมโพเนนต์ของคุณมีปัญหา สำหรับคันล่างส่วนล่างสาเหตุเฉพาะจะอยู่ในข้อยกเว้นภายใน


นั่นยุติธรรม ดังนั้นคุณแนะนำไม่สร้างข้อยกเว้นใหม่เมื่อมีดีอยู่แล้ว

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