มันมีเหตุผลหรือไม่ที่จะบันทึกข้อยกเว้นใน catch-all หรือในคลาส exception ยกเว้น?


15

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

ในการผลิตฉันใช้ catch-all exception ทั่วไปผ่านset_exception_handlerและฉันกำลังจะเพิ่มการบันทึก exception *ให้กับ mix ขึ้นเขียงของฉันคือที่ที่จะทำการบันทึกที่แท้จริงในคลาสยกเว้นฐานหรือใน catch-all

ฉันคิดถึงเหตุผลสองสามข้อในการเข้าสู่ระบบทั้งหมด:

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

และเหตุผลหนึ่งในการเข้าสู่คลาสยกเว้นฐาน:

  • ปัจจุบัน catch-all ใช้กับการผลิตเท่านั้น มันจะง่ายต่อการแนะนำในสภาพแวดล้อมอื่น ๆ ของเรา (การพัฒนาการทดสอบ) แต่ที่จะเรียกร้องให้มีการปรับเปลี่ยนเล็กน้อยเนื่องจากข้อผิดพลาดจะได้รับการจัดการแตกต่างกันไปตามสภาพแวดล้อมเช่นเดียวกับการผลิต

มีวิธีปฏิบัติที่ยอมรับได้สำหรับการบันทึกข้อยกเว้นหรือไม่

* การบันทึกจะเกี่ยวข้องกับการเขียนไปยังไฟล์ข้อความในตอนแรกและมันอาจพัฒนาไปสู่การส่งอีเมลสำหรับข้อยกเว้นบางประเภท


คำอธิบายบางอย่างได้รับแจ้งจากคำตอบของ @ unholysampler :

ฉันกำลังเผชิญกับโค้ดเบส sloc ขนาด 2 * 10 ^ 6 พร้อมสิ่งต่าง ๆ มากมายที่ฉันไม่สามารถควบคุมได้และโค้ดบางตัวฉันสามารถควบคุมข้อยกเว้นก่อนวันใน PHP ได้ และยังมีรหัสล่าสุดที่เส็งเคร็งเรากำลังฟื้นตัวจากความกดดันที่ยาวนานซึ่งเราต้องหยุดคิดและแฮ็ค

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

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

คำตอบ:


11

ในระยะสั้นเพียงครั้งเดียวที่คุณควรบันทึกการมีอยู่ของข้อยกเว้นคือเมื่อคุณจัดการมัน

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

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

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

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


ฉันได้เพิ่มคำอธิบายบางอย่างสำหรับคำถามที่ได้รับคำตอบจากคุณ จากสิ่งที่ฉันรวบรวมในด้านการปฏิบัติของคำถามที่คุณเสนอให้เข้าสู่ระบบ catch-all?
yannis

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

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

3

หากภาษา / รันไทม์ของคุณไม่ช่วยให้คุณสามารถระบุแหล่งที่มาของข้อยกเว้นได้อย่างง่ายดายมีกรณีสำหรับการบันทึกไว้ที่การขว้าง C ++ และเอ็นจิน JS บางตัวไม่แสดงไฟล์ + บรรทัดหรือ call stack ของข้อยกเว้นตามเวลาที่คุณตรวจพบ / แต่ข้อมูลนี้มีอยู่ในเวลาที่คุณสร้างข้อยกเว้น

วิธีการแก้ปัญหาของเราคือการจัดเตรียมกลไกที่ใช้การกำหนดค่ารันไทม์เพื่อเปิดใช้งานการบันทึกประเภทของข้อยกเว้นพร้อมกับราคาถูก - กองซ้อนเมื่อพยายามวินิจฉัยปัญหาเหล่านี้


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