Design by Contract – Exceptions 9/10/2019 8:50 AM COSC3311 – Software Design Design by Contract – Exceptions Object Oriented Software Construction 10/09/2019 8:50 AM 0
OOSC2 Ch. 12 Exceptions Correct use of exceptions Division by zero Run out of memory when creating an object A void call A contract violation (See OOSC2 page 413) Correct use of exceptions Technique of last resort! Do not use it for normal flow of control Object Oriented Software Construction 10/09/2019 8:50 AM 1
Rescue Clause count: INTEGER transmit (m: MESSAGE) -- transmit ‘m’ on redundant channels 1..count local i: INTEGER do sent_to_transmitter(m,i) rescue i := i + 1 if i <= count then retry end Object Oriented Software Construction 10/09/2019 8:50 AM 2
The original strategy r (...) is require ... do op1 op2 opi opn rescue end Fails, triggering an exception in r (r is recipient of exception). Object Oriented Software Construction 10/09/2019 8:50 AM 3
The call chain Routine call r0 r1 r2 r3 r4 Object Oriented Software Construction 10/09/2019 8:50 AM 4
Handling exceptions properly Safe exception handling principle: There are only two acceptable ways to react for the recipient of an exception: Concede failure, and trigger an exception in the caller (Organized Panic). Try again, using a different strategy (or repeating the same strategy) (Retrying). Object Oriented Software Construction 10/09/2019 8:50 AM 5
9/10/2019 8:50 AM How not to do it Normal Return to Caller as if nothing strange has happened (might cause an artillery shot to head in the wrong direction) (From an Ada textbook) sqrt (x: REAL) return REAL is begin if x < 0.0 then raise Negative; else normal_square_root_computation; end exception when Negative => put ("Negative argument"); return; when others => Ada does not have assertions – hence defensive for negative The main problem is that put(“Negative argument”) return will return to the original caller as if nothing strange has happened (this might direct the artillery shot in the wrong direction). Object Oriented Software Construction 10/09/2019 8:50 AM 6
Java Version – also problematic public class Sample { public static void main (String[] args) { System.out.println(sqrt(523)); //23 x 23 } private static double sqrt (double i) { double result = -1; try{ result = Math.sqrt(i); } catch (ArithmeticException ae){ System.out.println("Real numbers only!"); // i.e. do a normal return // as if nothing has happened! } return result; } } Object Oriented Software Construction 10/09/2019 8:50 AM 7
Better Java Code Assume we create a subclass of java.lang.Exception called SquareRootException. The sqrt method should be changed as follows: private static double sqrt (double x) throws SquareRootException { double result = -1; try {result = Math.sqrt(x)} catch (ArithmeticException ae) { throw new SquareRootException ("Bad param:"+x); } return result; } Object Oriented Software Construction 10/09/2019 8:50 AM 8
Dealing with Exceptions in Java 9/10/2019 8:50 AM Dealing with Exceptions in Java We as programmers want to write quality code that solves problems. Unfortunately, exceptions come as side effects of our code. No one likes side effects, so we soon find our own ways to get around them. I have seen some smart programmers deal with exceptions the following way: public void consumeAndForgetAllExceptions () { try { ...some code that throws exceptions } catch (Exception ex){ ex.printStacktrace(); } } What is wrong with the code above? Once an exception is thrown, normal program execution is suspended and control is transferred to the catch block. The catch block catches the exception and just suppresses it. Execution of the program continues after the catch block, as if nothing had happened. http://www.onjava.com/pub/a/onjava/2003/11/19/exceptions.html Object Oriented Software Construction 10/09/2019 8:50 AM 9
Better public void dontconsumeAndForgetAllExceptions () { try { ...some code that throws exceptions } catch (Exception ex) { throw new RuntimeException(ex); } Object Oriented Software Construction 10/09/2019 8:50 AM 10
Eiffel Exception mechanism Two constructs: A routine may contain a rescue clause. A rescue clause may contain a retry instruction. A rescue clause that does not execute a retry leads to failure of the routine (this is the organized panic case). Object Oriented Software Construction 10/09/2019 8:50 AM 11
Transmitting over an unreliable line (1) Max_attempts: INTEGER is 100 attempt_transmission (message: STRING) is -- Transmit message in at most -- Max_attempts attempts. local failures: INTEGER do unsafe_transmit (message) rescue failures := failures + 1 if failures < Max_attempts then retry end end Object Oriented Software Construction 10/09/2019 8:50 AM 12
Transmitting over an unreliable line (2) Max_attempts: INTEGER = 100 failed: BOOLEAN attempt_transmission (message: STRING) -- Try to transmit message; -- if impossible in at most Max_attempts -- attempts, set failed to true. local failures: INTEGER do if failures < Max_attempts then unsafe_transmit (message) else failed := True end rescue failures := failures + 1 retry Object Oriented Software Construction 10/09/2019 8:50 AM 13
If no exception clause (1) Absence of a rescue clause is equivalent, in first approximation, to an empty rescue clause: f (...) is do ... end is an abbreviation for f (...) is do ... rescue -- Nothing here end (This is a provisional rule; see next.) Object Oriented Software Construction 10/09/2019 8:50 AM 14
The correctness of a class create a.make (…) (1-n) For every exported routine r: {INV and prer} dor {INV and postr} (1-m) For every creation procedure cp: {precp} docp {postcp and INV} S1 a.f (…) S2 a.g (…) S3 a.f (…) S4 Object Oriented Software Construction 10/09/2019 8:50 AM 15
Exception correctness: A quiz For the normal body: {INV and prer} dor {INV and postr} For the exception clause: { ??? } rescuer { ??? } Object Oriented Software Construction 10/09/2019 8:50 AM 16
Quiz answers For the normal body: {INV and prer} dor {INV and postr} For the exception clause: {True} rescuer {INV} Object Oriented Software Construction 10/09/2019 8:50 AM 17
If no exception clause (2) Absence of a rescue clause is equivalent to a default rescue clause: f (...) is do ... end is an abbreviation for f (...) is do ... rescue default_rescue end The task of default_rescue is to restore the invariant. Object Oriented Software Construction 10/09/2019 8:50 AM 18
The Cook and the Firefighter (1) Two noble professions Cook Firefighter Object Oriented Software Construction 10/09/2019 8:50 AM 19
The Cook and the Firefighter (2) assumes when showing up for work that the restaurant is not on fire (invariant) must prepare a good meal (postcondition) Firefighter May assume nothing about the state of the restaurant on first entry (True precondition) Returns the restaurant to the non-burning state (invariant) Not responsible for cooking a meal. Object Oriented Software Construction 10/09/2019 8:50 AM 20
For finer-grain exception handling Use class EXCEPTIONS from the Kernel Library. Some features: exception (code of last exception that was triggered). is_assertion_violation, etc. raise (“exception_name”) Object Oriented Software Construction 10/09/2019 8:50 AM 21