มีข้อยกเว้นโดยทั่วไปเพื่อป้องกันระบบล่มหรือไม่?


16

ประการที่สองฉันสงสัยว่าถ้าใครรู้ว่าอะไรคือความแตกต่างระหว่างข้อยกเว้น (ในขอบเขตของโฟลว์การควบคุมข้อยกเว้น) และข้อยกเว้น (เช่นที่ใช้ใน Java)

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

คำตอบ:


29

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

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

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


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

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

16

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

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


5

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

ที่กล่าวว่าไม่มีข้อยกเว้นไม่มีอยู่เพื่อป้องกันไม่ให้ระบบ "crashing" มีข้อยกเว้นทำให้ฉันรู้ว่ามีปัญหา ฉันจะดำเนินการกำหนดได้อย่างไรว่าระบบ "ขัดข้อง" หรือไม่

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


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


2
ฉันไม่เห็นด้วยนิยามนี้ จำกัด เกินไป ควรแสดงชุดย่อยของข้อยกเว้นให้กับผู้ใช้เท่านั้น ข้อยกเว้นสำหรับการจัดการข้อผิดพลาดและการเลิกและแจ้งผู้ใช้เป็นขั้นตอนสุดท้ายที่มักเกิดขึ้นและไม่ควรเป็นบรรทัดฐาน ระบบบางระบบได้รับการออกแบบให้ใช้ข้อยกเว้นสำหรับการควบคุมการไหลในบางประเภทเช่นจุดจบ, EOF เป็นต้น
Jürgen Strobel

Jürgenฉันเข้าใจและเห็นด้วยกับความคิดเห็นของคุณอย่างสมบูรณ์ "แก้ไขหรือกลายเป็นข้อผิดพลาดที่มีความหมาย" - ฉันไม่ได้ถ่ายทอดความคิดนั้นด้วยคำพูดนี้หรือไม่?

ใช่มันดีขึ้นแล้ว
Jürgen Strobel

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

2

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

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

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


มีข้อ จำกัด เกี่ยวกับระบบปฏิบัติการที่สามารถล้างข้อมูลได้ โดยทั่วไปแล้วระบบปฏิบัติการไม่สามารถรู้ได้ว่าจะต้องล้างทรัพยากรหรือไฟล์ที่เก็บถาวร (เช่นไฟล์) หรือไม่และไม่สามารถทราบได้ว่ามีการล้างข้อมูลที่จำเป็นสำหรับการเชื่อมต่อระยะไกลหรือไม่
8bittree

2

มันง่ายมาก

  • เพื่อให้โปรแกรมทำงานผิดพลาดและไม่ใช่ทั้งระบบ - เรามี [ดี] ระบบปฏิบัติการ
  • หากต้องการหยุดทำงานโปรแกรมแทนการเพิกเฉยข้อผิดพลาดร้ายแรง - เรามีข้อยกเว้น

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

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

ดังนั้นจึงตัดสินใจเมื่อมีข้อผิดพลาดเกิดขึ้นซึ่งคุณไม่ได้คำนึงถึงความผิดพลาดเกิดขึ้นทันที! การจัดการข้อยกเว้น AKA


1

ข้อยกเว้นเป็นเพียงกลไกการตรวจจับข้อผิดพลาด พวกเขาไม่มีประโยชน์

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


0

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

ทำให้รหัสชัดเจนและง่ายต่อการบำรุงรักษามากขึ้น

ลองพิจารณาโค้ด sniplets สองตัว:

try:
    do1()  # this is obvoiusly a normal
    do2()  # program flow
except:
    oups()  # this is exception handling code

เปรียบเทียบกับอันนี้:

if foo():
    thing1()  # is this part of normal program flow?
else:
    thing2()  # or maybe this one? Or both? When?

แน่นอนว่าสามารถใช้การจัดการข้อยกเว้นเพื่อป้องกันไม่ให้โปรแกรมหยุดทำงานโดย:

try {    // very bad code
    my();
    whole();
    ugly();
    application();
    here();
} catch (Throwable t) {
    // pretend it's ok
}

แต่นี่ไม่ใช่เหตุผลสำหรับข้อยกเว้นในภาษาการเขียนโปรแกรมที่ทันสมัย

นอกจากนี้คุณยังสามารถใช้whileและbreakแทนที่ifแต่นี่ไม่ใช่สิ่งที่whileและbreakมีไว้เพื่อ


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

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