วิธีใช้งานการจัดการข้อผิดพลาด [ปิด]


13

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

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

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

ฉันรหัสใน C # ส่วนใหญ่


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

6
คำถามของคุณกว้างมาก บางทีคุณอาจ จำกัด ขอบเขตให้แคบลงโดยเกี่ยวข้องกับตัวอย่างเฉพาะของวิธีที่คุณล้มเหลวในการบรรลุเป้าหมายในการเขียนโค้ด
Andyz Smith

มีบทความมากมายบนเว็บเกี่ยวกับการจัดการข้อผิดพลาด: ลองทำสิ่งนี้: msdn.microsoft.com/en-us/library/seyhszts.aspx
Nir Kornfeld

คำตอบ:


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

  2. อย่าใช้ข้อยกเว้นเพื่อจัดการรหัสที่ไม่ถูกต้อง ในการตรวจสอบความถูกต้องของรหัสคุณควรใช้การยืนยันหรือใน. NET Framework 4 และหลังจากนั้นสัญญารหัส (ซึ่งแทนที่การยืนยันและมีคุณสมบัติที่มีคุณค่าเพิ่มเติมโดยเฉพาะ)

  3. อย่าใช้ข้อยกเว้นในกรณีพิเศษ ความจริงที่ว่าผู้ใช้เมื่อได้รับแจ้งให้ป้อนหมายเลขให้ป้อน "dog" นั้นไม่ได้เป็นข้อยกเว้นที่ยอดเยี่ยมในการได้รับการยกเว้น

  4. ระวังเมื่อเลือกประเภทของข้อยกเว้น สร้างประเภทของคุณเองเมื่อต้องการ เลือกมรดกอย่างระมัดระวังโดยคำนึงว่าผู้ปกครองจะจับเด็กเช่นกัน throw Exceptionไม่เคย

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

  6. ในกรณีที่คาดว่าวิธีการที่จะกลับข้อผิดพลาดและข้อผิดพลาดไม่ได้เป็นพิเศษให้ใช้ enums ไม่เคยหมายเลขข้อผิดพลาด ตัวอย่าง:

    // Note that the operation fails pretty often, since it deals with the servers which are
    // frequently unavailable, and the ones which send garbage instead of the actual data.
    private LoadOperationResult LoadProductsFromWeb()
    {
        ...
    }
    

    ความหมายของLoadOperationResult.ServerUnavailable, LoadOperationResult.ParsingErrorฯลฯ มีความชัดเจนมากกว่าพูดการจดจำรหัส 12 หมายความว่าเซิร์ฟเวอร์หยุดทำงานและรหัส 13 - ที่ไม่สามารถแยกวิเคราะห์ข้อมูลได้

  7. ใช้รหัสข้อผิดพลาดเมื่ออ้างถึงรหัสทั่วไปซึ่งนักพัฒนาซอฟต์แวร์ทุกคนรู้จักซึ่งทำงานในโดเมนที่ระบุ ตัวอย่างเช่นอย่าสร้างค่า enum สำหรับ HTTP 404 Not Found หรือ HTTP 500 Internal Server Error

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

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

  10. ใน C # ไม่ต้องรื้อฟื้นข้อยกเว้นเช่นนี้อีก:

    catch (SomeException ex)
    {
        ...
        throw ex;
    }
    

    เพราะคุณทำลายสแต็ค ทำสิ่งนี้แทน:

    catch (SomeException)
    {
        ...
        throw;
    }
    
  11. ใช้ความพยายามเมื่อเขียนข้อความยกเว้น กี่ครั้งที่ผมเคยเห็นสิ่งที่ต้องการหรือthrow Exception("wrong data") throw Exception("shouldn't call this method in this context")นักพัฒนาคนอื่น ๆ รวมถึงตัวคุณเองในอีกหกเดือนต่อมาจะไม่รู้ว่าข้อมูลผิดอะไรและทำไมหรือทำไมเราไม่ควรเรียกวิธีการบางอย่างในบริบทหรือบริบทใด

  12. อย่าแสดงข้อความแสดงข้อยกเว้นต่อผู้ใช้ พวกเขาไม่คาดหวังสำหรับคนธรรมดาและมักจะไม่สามารถอ่านได้สำหรับนักพัฒนาซอฟต์แวร์เอง

  13. อย่า จำกัด ข้อความยกเว้น การค้นหาเอกสารสำหรับข้อความที่แปลเป็นภาษาท้องถิ่นหมดแล้วและไร้สาระ: ทุกข้อความควรเป็นภาษาอังกฤษและภาษาอังกฤษเท่านั้น

  14. อย่ามุ่งเน้นที่ข้อยกเว้นและข้อผิดพลาดเฉพาะ: บันทึกเป็นสิ่งที่สำคัญอย่างยิ่ง

  15. ใน. NET อย่าลืมที่จะรวมข้อยกเว้นในเอกสาร XML ของวิธีการ:

    /// <exception cref="MyException">Description of the exception</exception>

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

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


¹สิ่งนี้ถูกกล่าวว่าฉันพบความแตกต่างของ Java ระหว่างข้อยกเว้นและข้อผิดพลาดค่อนข้างไร้ประโยชน์และสับสนเนื่องจากภาษาได้ตรวจสอบและตรวจสอบข้อยกเว้นแล้ว โชคดีที่. NET Framework มีข้อยกเว้นเท่านั้นและไม่มีข้อผิดพลาด


ฉันเรียนรู้ที่จะพูดจากสิ่งนี้ฉันขอถามว่ารายการมาจากไหน? เว็บไซต์หรือประสบการณ์ส่วนตัว? ไม่ว่าจะเป็นงานที่ยอดเยี่ยมทางไหน
Shelby115

@ Shelby115: รายการมาจากตามลำดับ: Stack Exchange, ประสบการณ์ส่วนตัวและโค้ดที่สมบูรณ์โดย Steve Mcconnell
Arseni Mourzenko

ขอบคุณ @MainMa นั่นเป็นคำตอบที่ยอดเยี่ยม! ฉันเคยเป็นเจ้าของ Code Complete เมื่อฉันอยู่ที่มหาวิทยาลัย แต่มีคนขโมยมัน ฉันไม่ได้อ่าน
James Jeffery

@JamesJeffery: จากนั้นยืมฉบับที่สองในห้องสมุดหรือซื้อ: เป็นหนึ่งในหนังสือที่เกี่ยวกับการพัฒนาที่หายากซึ่งคุ้มค่ากับเงินทั้งหมด
Arseni Mourzenko

@MainMa เพิ่งได้รับคำสั่งจาก Amazon ขอบคุณ: DI ยังเป็นเจ้าของ Clean Code และลืมไปโดยสิ้นเชิงเกี่ยวกับบทที่ 7
James Jeffery

1

ฉันคิดว่ารายการ MainMa นั้นสมบูรณ์มาก ฉันจะเพิ่มของฉันเอง:

  1. อ่านบทความของ Eric Lippert เกี่ยวกับวิธีที่เขาจัดหมวดหมู่ข้อยกเว้น สิ่งที่สำคัญอย่างยิ่งคือประเด็นของเขาที่ไม่ได้รับการยกเว้นที่เป็นข้อบกพร่องในรหัส แก้ไขรหัสแทน!
  2. หากคุณรู้ว่ามีข้อยกเว้นเกิดขึ้นและคุณสามารถทำอะไรกับมันจัดการได้ แต่ จำกัด ขอบเขตของการลองจับและจับข้อยกเว้นเฉพาะที่คุณคาดหวัง นั่นคืออย่าทำสิ่งนี้:

public void Foo() {
    try {
        //get input from use
        //do calculations
        //open file
    }
    catch (Exception ex) {
       //handle exception
    }
}

ทำสิ่งนี้แทน:

public void Foo() {
    //get input from use
    //do calculations
    try {
        //open file
    }
    catch (FileOpenException ex) {
       //handle exception
    }
}
  • อย่าใช้ข้อยกเว้นสำหรับโฟลว์การควบคุม ตัวอย่างเช่นอย่าโยน ClientNotFoundException ในกล่องโต้ตอบการค้นหา (ลูกค้าไม่พบไม่เป็นพิเศษในสถานการณ์นี้) และคาดว่ารหัสการโทรจะแสดงข้อความ "ไม่พบผลลัพธ์" เมื่อสิ่งนี้เกิดขึ้น

  • อย่ากลืนข้อยกเว้น!

  • โปรดทราบว่าการจัดการข้อยกเว้นอย่างแท้จริงอาจหมายถึง 3 สิ่งเท่านั้น:

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

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

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