เหตุใดข้อความยกเว้นจำนวนมากจึงไม่มีรายละเอียดที่เป็นประโยชน์


220

ดูเหมือนจะมีจำนวนหนึ่งของข้อตกลงที่ข้อความยกเว้นควรมีรายละเอียดที่เป็นประโยชน์

ทำไมจึงเป็นเช่นนั้นข้อยกเว้นที่พบบ่อยจำนวนมากจากส่วนประกอบของระบบไม่มีรายละเอียดที่เป็นประโยชน์

ตัวอย่างบางส่วน:

  • การListเข้าถึงดัชนี. NET ArgumentOutOfRangeExceptionไม่ได้บอกค่าดัชนีที่พยายามแล้วและไม่ถูกต้องและไม่ได้บอกช่วงที่อนุญาต
  • โดยทั่วไปข้อความข้อยกเว้นทั้งหมดจากไลบรารีมาตรฐาน MSVC C ++ นั้นไร้ประโยชน์อย่างเต็มที่ (ในหลอดเลือดดำเดียวกันกับด้านบน)
  • ข้อยกเว้นของออราเคิลใน .NET บอกคุณ (ถอดความ) "ตารางหรือมุมมองไม่พบ" แต่ไม่ได้ที่หนึ่ง

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


59
ควรสังเกตว่าจากผู้เชี่ยวชาญด้านความปลอดภัย "ข้อความผิดพลาดไม่ควรมีรายละเอียดเกี่ยวกับ internals ของระบบ" เป็นกฎง่ายๆ
Telastyn

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

9
@Snowman: ผู้ใช้ไม่สามารถเข้าถึงอะไรได้หากเป็นซอฟต์แวร์ฝั่งไคลเอ็นต์ เจ้าของเครื่องเป็นเจ้าของเครื่องจักรและสามารถรับได้ทุกอย่าง
Mason Wheeler


6
มีข้อมูลเพิ่มเติมที่คุณต้องการมีอยู่เสมอ ฉันค้นหาข้อความที่คุณให้เป็นตัวอย่างให้ค่อนข้างดี คุณสามารถแก้ไขข้อบกพร่องของปัญหาได้ ดีกว่า "ข้อผิดพลาด 0x80001234" (ตัวอย่างได้รับแรงบันดาลใจจาก Windows Update)
usr

คำตอบ:


204

ข้อยกเว้นไม่มีรายละเอียดที่เป็นประโยชน์เนื่องจากแนวคิดของข้อยกเว้นยังไม่ครบกำหนดภายในวินัยวิศวกรรมซอฟต์แวร์ดังนั้นโปรแกรมเมอร์จำนวนมากจึงไม่เข้าใจอย่างเต็มที่และดังนั้นจึงไม่ปฏิบัติต่ออย่างถูกต้อง

ใช่IndexOutOfRangeExceptionควรมีดัชนีที่แม่นยำซึ่งอยู่นอกช่วงเช่นเดียวกับช่วงที่ถูกต้องในเวลาที่มีการโยนทิ้งและเป็นที่น่ารังเกียจในนามของผู้สร้างรันไทม์. NET ที่ไม่มี ใช่table or view not foundข้อยกเว้นของ Oracle ควรมีชื่อของตารางหรือมุมมองที่ไม่พบและความจริงที่ว่ามันไม่ได้ดูถูกในนามของใครก็ตามที่รับผิดชอบเรื่องนี้

ความสับสนเกิดขึ้นจากแนวคิดดั้งเดิมที่เข้าใจผิดว่าข้อยกเว้นควรมีข้อความที่มนุษย์อ่านได้ซึ่งเกิดจากการขาดความเข้าใจในสิ่งที่เป็นข้อยกเว้นดังนั้นจึงเป็นวงจรอุบาทว์

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

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

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

เพื่อแก้ไขข้อกังวลที่แสดงออกโดย Thomas Owens ในความคิดเห็นด้านล่าง:

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

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

PS

ความคิดของฉันอีกสองสามข้อสามารถพบได้ในคำตอบนี้: วิธีการเขียนข้อความยกเว้นที่ดี

PPS

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


4
ฉันได้ดูบางคลาสยกเว้นใน. NET Framework และปรากฎว่ามีโอกาสมากมายสำหรับการเพิ่มข้อมูลชนิดนี้โดยทางโปรแกรม ดังนั้นฉันจึงเดาว่าคำถามจะเปลี่ยนเป็น "ทำไมพวกเขาถึงไม่ทำ" แต่ +1 สำหรับสิ่งที่ "อ่านได้" ทั้งหมด
Robert Harvey

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

44
ดังนั้นโปรแกรมเมอร์ไม่ใช่มนุษย์เหรอ? ดูที่เพื่อนร่วมงานของฉันนี่เป็นการยืนยันความสงสัยบางอย่างที่ฉันเคยทำมาสักพักแล้ว ...
gbjbaanb

51
อีกครั้งมีอะไรผิดปกติกับการปล่อยให้ผู้ใช้เห็นร่องรอยทั้งกองตราบใดที่ซอฟต์แวร์ที่ถูกฝั่งไคลเอ็นต์ โครงการซอฟต์แวร์ระดับมืออาชีพทุกโครงการที่ฉันเคยทำและส่วนใหญ่ของมือสมัครเล่นนั้นมีระบบการบันทึกที่จะสร้างการถ่ายโอนข้อมูลข้อผิดพลาดแบบเต็มเมื่อเกิดข้อยกเว้นที่ไม่สามารถจัดการได้รวมถึงร่องรอยสแต็กเต็มรูปแบบ กระบวนการ. และผู้ใช้สามารถ (อ้าปากค้างโอ้สยองขวัญ!) ดูได้ตลอดเวลาที่เขาต้องการเพราะมันเป็นสิ่งที่จำเป็น (ไม่เพียง แต่มีประโยชน์ แต่จำเป็น ) เพื่อส่งข้อความข้อผิดพลาดกลับมาหาเรา! เกิดอะไรขึ้นกับสิ่งนั้น?
Mason Wheeler

13
ฉันยังไม่มั่นใจเกี่ยวกับไฟล์บันทึกแบบไบนารีเท่านั้น ส่วนใหญ่เป็นเพราะประสบการณ์ของฉันกับ systemd เครื่องมือพิเศษสำหรับการดูบันทึกเหล่านี้ค่อนข้างสับสนและดูเหมือนว่าได้รับการออกแบบโดยคณะกรรมการของลิงของเช็คสเปียร์ พิจารณาว่าสำหรับเว็บแอปพลิเคชันบุคคลแรกที่เห็นข้อยกเว้นของคุณมักจะเป็นดูแลระบบและเขาจะต้องการตรวจสอบว่าเป็นสิ่งที่เขาต้องการแก้ไขหรือไม่ (เช่นดิสก์หมดพื้นที่) หรือส่งคืน เพื่อนักพัฒนา
Michael Hampton

46

ทำไมจึงเป็นเช่นนั้นข้อยกเว้นที่พบบ่อยจำนวนมากจากส่วนประกอบของระบบไม่มีรายละเอียดที่เป็นประโยชน์

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

  • ผู้คนที่มุ่งเน้นด้านความปลอดภัยจะมองเห็นข้อยกเว้นว่าเป็นแหล่งที่มาของการรั่วไหลของข้อมูล ( ตัวอย่าง ) เนื่องจากพฤติกรรมเริ่มต้นของข้อยกเว้นคือการแสดงข้อมูลนั้นให้กับผู้ใช้บางครั้งโปรแกรมเมอร์จึงผิดพลาดในด้านของความระมัดระวัง
  • ใน C ++ ฉันเคยได้ยินข้อโต้แย้งเกี่ยวกับการจัดสรรหน่วยความจำในบล็อก catch (อย่างน้อยบริบทบางอย่างที่ทำให้ข้อความดีอยู่) การจัดสรรนั้นยากที่จะจัดการและที่แย่กว่านั้นอาจทำให้เกิดข้อยกเว้นหน่วยความจำไม่เพียงพอ - มักจะทำให้แอพของคุณหรือหน่วยความจำรั่ว เป็นการยากที่จะจัดรูปแบบข้อยกเว้นเป็นอย่างดีโดยไม่ต้องจัดสรรหน่วยความจำและการฝึกฝนนั้นอาจมีการโยกย้ายระหว่างภาษาเช่นเดียวกับโปรแกรมเมอร์
  • พวกเขาไม่รู้ ผมหมายถึงมีเป็นสถานการณ์ที่รหัสมีไม่มีความคิดสิ่งที่ผิดพลาดไป หากรหัสไม่ทราบ - มันไม่สามารถบอกคุณได้
  • ฉันทำงานในสถานที่ที่มีข้อสงสัยเกี่ยวกับการแปลหลายภาษาทำให้ไม่สามารถใส่สายภาษาอังกฤษลงในระบบได้ - แม้จะมีข้อยกเว้นที่พนักงานให้ความช่วยเหลือพูดภาษาอังกฤษอ่านได้เท่านั้น
  • สถานที่บางแห่งฉันเคยเห็นข้อยกเว้นที่ใช้เช่นการอ้างสิทธิ์มากขึ้น พวกเขาอยู่ที่นั่นเพื่อให้ข้อความที่ชัดเจนและดังในระหว่างการพัฒนาที่สิ่งที่ไม่ได้ทำหรือมีการเปลี่ยนแปลงในที่เดียว แต่ไม่ใช่ที่อื่น สิ่งเหล่านี้มักจะไม่ซ้ำกันมากพอที่ข้อความที่ดีจะถูกทำซ้ำหรือทำให้สับสน
  • คนขี้เกียจโปรแกรมเมอร์มากกว่าคนส่วนใหญ่ เราใช้เวลาน้อยลงในเส้นทางที่พิเศษกว่าเส้นทางที่มีความสุขและนี่คือผลข้างเคียง

ความคาดหวังของฉันอยู่นอกสายหรือไม่? ฉันใช้ข้อยกเว้นผิดที่ฉันสังเกตเห็นสิ่งนี้ด้วยหรือไม่

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


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

1
@Lilienthal - เช่น? ไม่มีภาษาใดที่ฉันคุ้นเคยเป็นอย่างดี
Telastyn

1
ฉันคิดว่าคำตอบนี้มีเนื้อหาที่ดีมากมาย แต่ก็หลีกเลี่ยงการพูดบรรทัดล่างซึ่งก็คือ "พวกเขาควรจะ"
djechlin

3
ขอบคุณ ความกังวลของคุณไม่มีมูลความจริง (ฉันหวังว่า :-) แต่ทุกครั้งที่ฉันใช้เวลาเพิ่มอีกหนึ่งนาทีในการติดตามสิ่งที่ผิดพลาดในการทดสอบหน่วยนั้นหรือใช้เวลาวิเคราะห์รหัสเพิ่มเติมเนื่องจากไฟล์บันทึกข้อมูลขาดข้อมูลฉันรู้สึกหงุดหงิดกับความบ้าคลั่งที่หลีกเลี่ยงได้ของข้อความ :-)
Martin Ba

@Telastyn SAPAP ที่เป็นกรรมสิทธิ์ของ ABAP มีโครงสร้างคลาสยกเว้นสามารถมีข้อความซึ่งโดยทั่วไปวัตถุจะหมายถึงการรายงานสถานะของโปรแกรม (สำเร็จ, ล้มเหลว, คำเตือน) ให้กับผู้ใช้พร้อมกับข้อความแบบไดนามิก (หลายภาษา) ฉันจะยอมรับว่าไม่รู้ว่าสิ่งนี้แพร่หลายมากแค่ไหนหรือถ้ามันได้รับการสนับสนุนในภาษาก็เป็นไปได้ แต่ก็มีอย่างน้อยหนึ่งที่ซึ่งมันเป็นเรื่องธรรมดา
Lilienthal

12

ฉันไม่ได้มีประสบการณ์ C # มากเกินไปหรือ C ++ โดยเฉพาะ แต่ฉันสามารถบอกคุณได้ - ข้อยกเว้นที่เขียนโดยผู้พัฒนา 9 จาก 10 ครั้งนั้นมีประโยชน์มากกว่าข้อยกเว้นทั่วไปที่คุณจะพบในช่วงเวลา

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

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

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

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


7

คำถามนี้ถามโดยเฉพาะว่าทำไมข้อยกเว้นมากมายที่ส่งออกมาโดย "ส่วนประกอบของระบบ" (aka คลาสไลบรารีมาตรฐาน) ไม่มีรายละเอียดที่เป็นประโยชน์

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

อย่างไรก็ตามมีประเด็นสำคัญสองข้อที่ควรคำนึงถึงว่าทำไมข้อมูลข้อยกเว้นโดยละเอียดอาจไม่เป็นที่ต้องการหรือสำคัญ:

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

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


3
1. ตามเกณฑ์นี้ดูเหมือนว่าจะเป็นข้อมูลใด ("ดัชนีอยู่นอกช่วง", การติดตามสแต็ก) และไม่แสดง (ค่าดัชนี) 2. การดีบักอาจจะเร็วและง่ายขึ้นเมื่อทราบค่าไดนามิกที่เกี่ยวข้อง ตัวอย่างเช่นมันมักจะบอกคุณทันทีว่าปัญหาคือการป้อนขยะไปยังชิ้นส่วนของรหัสที่ล้มเหลวหรือรหัสนั้นล้มเหลวในการจัดการกับการป้อนข้อมูลที่ดีอย่างถูกต้อง
Ben Aaronson

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

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

@gbjbaanb ที่บอกว่าเราต้องการแสดงการติดตามสแต็กเต็มรูปแบบแก่ผู้ใช้

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

4

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

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

เมื่อเร็ว ๆ นี้ในแอปพลิเคชันที่ถูกสร้างใหม่การตัดสินใจถูกสร้างขึ้นเพื่อให้โค้ดส่งคืนตกอยู่ในกลุ่มใดกลุ่มหนึ่งจากสามกลุ่ม:

  • 0 ถึง 9 จะประสบความสำเร็จผ่านความสำเร็จพร้อมข้อมูลเพิ่มเติม
  • 10 ถึง 99 จะเป็นข้อผิดพลาดที่ไม่ร้ายแรง (กู้คืนได้) และ
  • 101 ถึง 255 จะเป็นข้อผิดพลาดร้ายแรง

(100 เป็นเพราะเหตุผลบางอย่างออก)

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

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

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

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

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

บันทึกล่าสุด: หากข้อความแสดงข้อผิดพลาดมีรหัสข้อผิดพลาด / ส่งคืนดูเหมือนว่าบางที่ในโมดูลที่ดำเนินการควรมีบรรทัดที่อ่านบางอย่างเช่น "ถ้าเงื่อนไขส่งคืนรหัส - ค่า" และเงื่อนไขควรบอกคุณว่าทำไมรหัสส่งคืน ที่เกิดขึ้น สิ่งนี้ดูเหมือนจะเป็นวิธีการทางตรรกะที่เรียบง่าย แต่สำหรับชีวิตของฉันลองใช้ Microsoft เพื่อบอกคุณว่าเกิดอะไรขึ้นเมื่อการอัปเกรด windows ล้มเหลวใน CODE 80241013 หรือตัวระบุเฉพาะอื่น ๆ ค่อนข้างเศร้าใช่มั้ย


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

3
chances are the users will never write it down... and you will be told "Well it said something about a violation..." นี่คือเหตุผลที่คุณใช้เครื่องมือการบันทึกข้อยกเว้นเพื่อสร้างรายงานข้อผิดพลาดที่มีการติดตามสแต็กโดยอัตโนมัติและอาจส่งไปยังเซิร์ฟเวอร์ของคุณ ฉันมีผู้ใช้หนึ่งครั้งในเวลาที่ไม่ได้มีเทคนิคมาก ทุกครั้งที่เธอจะส่งข้อความจากตัวบันทึกข้อผิดพลาดมันจะมีลักษณะเช่น "ฉันไม่แน่ใจว่าสิ่งที่ฉันทำผิด แต่ ... " ไม่ว่ากี่ครั้งที่ฉันอธิบายว่าข้อผิดพลาดนี้หมายถึงข้อผิดพลาดอยู่ข้างฉัน . แต่ฉันได้รับรายงานข้อผิดพลาดจากเธอเสมอ!
Mason Wheeler

3

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

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

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

แต่ถ้าคุณได้รับการยกเว้นและนำกลับมาใช้ใหม่ด้วยคำสั่ง SQL ที่คุณพยายามที่จะดำเนินการคุณจะดีขึ้นเนื่องจากปรากฎว่าคุณพยายามแทรกระเบียนด้วยฟิลด์ชื่อเป็นRobert '); วางตารางนักเรียน (มี xkcd เสมอ!)

ดังนั้นเพื่อต่อสู้กับข้อยกเว้นที่น้อยกว่าข้อมูล: ลองจับอีกครั้งด้วยข้อมูลเพิ่มเติมเฉพาะกับสิ่งที่คุณพยายามทำ

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


เช่นใน C ++ คุณควรใช้throw_with_nestedบ่อย
Miles Rout

3

หากต้องการให้คำตอบที่ต่างออกไปเล็กน้อย: รหัสที่ละเมิดอาจถูกทำเพื่อสเป็ค:

  • ฟังก์ชันรับ X และส่งคืน Y
  • ถ้า X ไม่ถูกต้องให้โยน exception Z

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


3

ข้อยกเว้นมีค่าใช้จ่ายเฉพาะด้านภาษาและการใช้งาน

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

ใน Ocaml การยกเว้นการโยนนั้นเร็วพอ ๆ กับ C setjmp(ค่าใช้จ่ายนั้นไม่ขึ้นอยู่กับจำนวนเฟรมการโทรที่ถูกสำรวจ) ดังนั้นนักพัฒนาสามารถใช้มันได้เป็นจำนวนมาก ในทางตรงกันข้ามข้อยกเว้น C ++ นั้นหนักพอที่คุณจะไม่ใช้มันอย่างที่คุณต้องการใน Ocaml

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

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


6
"ตัวอย่างเช่นจำเป็นต้องมีข้อยกเว้น C ++ ในการทำลายข้อมูลที่มีชีวิตทั้งหมดระหว่างการโยนกรอบการโทรและการจับกรอบการโทรและนั่นก็มีค่าใช้จ่ายสูงดังนั้นโปรแกรมเมอร์ไม่ต้องการใช้ข้อยกเว้นมากนัก" รวมอึ จุดแข็งหลักของข้อยกเว้น C ++ คือ destructors ถูกเรียกว่า deterministically ไม่มีใครจะใช้พวกเขาหากพวกเขาเพิ่งกระโดด
Miles Rout

ฉันรู้ว่า แต่มันเป็นความจริงที่ว่าข้อยกเว้น C ++ ไม่เหมือน Ocaml และคุณไม่ได้ใช้มันอย่างที่คุณทำใน Ocaml
Basile Starynkevitch เมื่อ

5
คุณไม่ได้ใช้ข้อยกเว้น C ++ สำหรับโฟลว์การควบคุมใน C ++ เป็นหลักเนื่องจากการทำเช่นนี้จะทำให้โค้ดอ่านไม่ได้และเข้าใจยาก
Miles Rout

-2

อะไรทำให้คุณคิดว่าค่าดัชนีหรือช่วงที่ต้องการหรือชื่อของตารางเป็นรายละเอียดที่มีประโยชน์ยกเว้น?

ข้อยกเว้นไม่ใช่กลไกการจัดการข้อผิดพลาด พวกเขาเป็นกลไกการกู้คืน

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

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

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


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

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

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

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

@Odalrick สำหรับลูกค้าที่มันอาจจะไม่ได้มีความหมายใด ๆ แต่เป็นนักพัฒนาผมให้ข้อมูลที่ฉันจะได้รับ ;-) แล้วบางทีอีกตัวอย่างหนึ่งทุกสมมติว่า SqlExeption เกิดขึ้นและที่ว่าทุกสิ่งที่คุณรู้ว่า ... มันเป็นเรื่องง่ายที่จะซ่อมแซมมัน ถ้าคุณรู้ว่าสตริงการเชื่อมต่อหรือฐานข้อมูลหรือตาราง ฯลฯ ไม่ทำงาน .... และนี่เป็นสิ่งที่สำคัญยิ่งกว่าหากแอปพลิเคชันของคุณใช้หลายฐานข้อมูล การติดตามสแต็กอย่างละเอียดต้องการไฟล์ pdb ที่จะจัดส่งพร้อมกับแอปพลิเคชัน ... ไม่สามารถทำได้ การทิ้งหน่วยความจำอาจมีขนาดใหญ่มากและไม่สามารถถ่ายโอนได้ตลอดเวลา
t3chb0t
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.