CSE 305 Introduc0on to Programming Languages Lecture 18 – Excep0on Handling CSE @ SUNY-­‐Buffalo Zhi Yang Courtesy of T. PraM and M. Zelkowitz Courtesy of Stroustrup Courtesy of Richard S. Huntrods Courtesy of Professor Robert R. Perkoski No0ce Board • First, August 1, 2013, we will be having 4th long quiz, and you can schedule 0me reviewing accordingly. • Second, homework7 has been posted, and it is worth 20 in total (10 points for bonus). Our objec0ve • The first objec0ve of our class, is to comprehend a new programming language within very short 5me period, and because you have this ability to shorten your learning curve, you are going to manipulate the language with an insight learning. • The second objec0ve is to even engineer your own language! Review what we ve learnt and see future eg: Egyp0an Number System; Complement Number eg: Abacus Number System eg: Gate system, Including different underline device 1st Genera0on language: Machine Code eg: MIPS 2nd Genera0on language: Assembly Code eg: Fortran Regular Expression What s next ? 3rd Genera0on Language: Macro func0on Macro func5on Basic Calcula0on System Lexer Compiler System Virtual Machine Parser Push Down Automata Type Checking Context-­‐Free Grammar Lambda Calculus Theory A family tree of languages Cobol <Fortran> BASIC Algol 60 <LISP> PL/1 Simula <ML> Algol 68 C Pascal <Perl> <C++> Modula 3 <PHP> Dylan Ada <Java> <C#> <Scheme> <Smalltalk> <Ruby> <Python> <Haskell> <Prolog> <JavaScript> Excep0on handling • Events in a program some0mes occur at unpredictable 0mes, I.e., apparently randomly. • That is, the occurrence is an excep0on to the normal sequencing of events. Such events are called excep0ons, and programming language constructed designed to handle these are called excep0on handlers. • Excep0ons can be created by the hardware or by sogware: • Examples Power failure, Printer out of paper, End of page, Divide by 0, End of array reached Tes0ng for excep0ons • • • Although sogware excep0ons can be tested in the code, the existence of an excep0on handling mechanism relieves the programmer the burden of constantly checking for this condi0on. Without excep0ons, need to test at each print statement: print data; if end-­‐of-­‐page then call newPage(); With automa0c excep0ons, setup mechanism: [PL/I example:] On endpage begin put page; end; /* Resume execu0on */ can write output without checking end-­‐page condi0on each 0me Implementa0on of excep0ons Excep0ons come from two sources: condi0ons detected by the virtual machine, and condi0ons generated by the seman0cs of the programming language. • In the former case, opera0ng system excep0ons may be raised directly by hardware interrupts or traps, such as arithme0c overflow, or they may be raised in support sogware, such as end-­‐of-­‐file condi0on. • In C, the programmer has direct access to these signals processed by the opera0ng system. The programmer may enable an interrupt (e.g., the sigac0on func0on in Unix, which specifies a procedure that gets invoked when the given signal is raised). • Excep0ons in ML • One can throw an excep0on and a handler will catch the excep0on. (More limited than PL/I example. Need to explicitly raise an excep0on.): fun doDivide(a,b) = if b=0 then raise badDenominator else a/b; • Note: fun divide(a,b) = doDivide(a,b) handle badDenominator => (print Divide error ; 0.0); doDivide is within dynamic scope of divide. Seman0cs if excep0on is raised: -­‐ If no handler, end func0on -­‐ Check dynamic scope of execu0ng procedures to look for appropriate handler -­‐ If handler, execute handler, then return to excep0on point (e.g., print message and return 0.0 as default value in above example.) Excep0ons in C++ • try clause implements excep0ons. Similar to ML: try { statements . . . If b=0 throw badDenominator; } catch badDenominator { Do something; }; • Propaga0ng excep0ons: If no local excep0on handler, who catches excep0on? Usually dynamic links checked for handler try statement terminates ager handling excep0on. Excep0ons in Ada • procedure Sub is Bad_Data_Value: excep0on; -­‐other declara0ons for Sub Begin excep0on end; • -­‐statements for normal processing in Sub raise Bad_Data_Value -­‐-­‐ to raise this excep0on when Bad_Data_Value => -­‐handler for bad data values when Constraint_Error =>-­‐handler for predefined excep0on Constraint_Error when others =>-­‐handler for all other excep0ons [Constraint_Error (e.g., number too large) is a built-­‐in excep0on in Ada.] More on implementa0on of excep0ons • • • • the language translator may insert addi0onal instruc0ons. For example, to detect Index_Check caused by an invalid array subscript, the translator inserts instruc0ons at each reference to an array, such as A[I,J], to determine whether the values of I and J are within the declared bounds. Unless the hardware or opera0ng system provides the excep0on checking, checking for an excep0on requires sogware simula0on. Ogen this cost is large. For example, it may take longer to perform the subscript bounds check on A[I,J] than it does to access the element of the array. Because of this extra cost, most languages provide a means to turn off checking for excep0ons in parts of the program where the programmer determines it is safe to do so [e.g., pragma Supress(Index_Check) in Ada]. Note: programmers are notoriously bad in determining when it is safe to do so. Asser0ons • An asser0on is a predicate that checks for an invalid value and then raises an excep0on: In C++: #include <assert.h> . . . assert(x,y); In C++ it is really a macro that generates: if (x>y) {/* Print error message */} Sources of errors • Poor specifica0on – What s this supposed to do? • Incomplete programs – but I ll not get around to doing that un0l tomorrow • Unexpected arguments – but sqrt() isn t supposed to be called with -­‐1 as its argument • Unexpected input – but the user was supposed to input an integer • Code that simply doesn t do what it was supposed to do – so fix it! Kinds of Errors • Compile-­‐0me errors – Syntax errors – Type errors • Link-­‐0me errors • Run-­‐0me errors – Detected by computer (crash) – Detected by library (excep0ons) – Detected by user code • Logic errors – Detected by programmer (code runs, but produces incorrect output) Check your inputs • Before trying to use an input value, check that it meets your expecta0ons/requirements – Func0on arguments – Data from input (istream) Bad func0on arguments • The compiler helps: – Number and types of arguments must match int area(int length, int width) { return length*width; } int x1 = area(7); // error: wrong number of arguments int x2 = area("seven", 2); // error: 1st argument has a wrong type int x3 = area(7, 10); // ok int x5 = area(7.5, 10); // ok, but dangerous: 7.5 truncated to 7; // most compilers will warn you int x = area(10, -­‐7); // this is a difficult case: // the types are correct, // but the values make no sense Bad Func0on Arguments • • • So, how about int x = area(10, -­‐7); Alterna0ves – Just don t do that • Rarely a sa0sfactory answer – The caller should check • Hard to do systema0cally – The func0on should check • Return an error value (not general, problema0c) • Set an error status indicator (not general, problema0c – don t do this) • Throw an excep0on Note: some0mes we can t change a func0on that handles errors in a way we do not like – Someone else wrote it and we can t or don t want to change their code Bad func0on arguments • Why worry? – You want your programs to be correct – Typically the writer of a func0on has no control over how it is called • Wri0ng do it this way in the manual (or in comments) is no solu0on – many people don t read manuals – The beginning of a func0on is ogen a good place to check • Before the computa0on gets complicated • When to worry? – If it doesn t make sense to test every func0on, test some How to report an error • • • Return an error value (not general, problema0c) int area(int length, int width) // return a nega@ve value for bad input { if(length <=0 || width <= 0) return -­‐1; return length*width; } So, let the caller beware int z = area(x,y); if (z<0) error("bad area computa5on"); // … Problems – What if I forget to check that return value? – For some func0ons there isn t a bad value to return (e.g. max()) How to report an error • • • Set an error status indicator (not general, problema0c, don t!) int errno = 0; // used to indicate errors int area(int length, int width) { if (length<=0 || width<=0) errno = 7; // || means or return length*width; } So, let the caller check int z = area(x,y); if (errno==7) error("bad area computa5on"); // … Problems – What if I forget to check errno? – How do I pick a value for errno that s different from all others? – How do I deal with that error? How to report an error • • Report an error by throwing an excep0on class Bad_area { }; // a class is a user defined type // Bad_area is a type to be used as an excep@on int area(int length, int width) { if (length<=0 || width<=0) throw Bad_area(); // note the () return length*width; } Catch and deal with the error (e.g., in main()) try { int z = area(x,y); // if area() doesn t throw an excep@on } // make the assignment and proceed catch(Bad_area) { // if area() throws Bad_area(), respond cerr << "oops! Bad area calcula5on – fix program\n"; } Excep0ons • Excep0on handling is general – You can t forget about an excep0on: the program will terminate if someone doesn t handle it (using a try … catch) – Just about every kind of error can be reported using excep0ons • You s0ll have to figure out what to do about an excep0on (every excep0on thrown in your program) – Error handling is never really simple Out of range • Try this vector<int> v(10); // a vector of 10 ints, // each ini@alized to the default value, 0, // referred to as v[0] .. v[9] for (int i = 0; i<v.size(); ++i) v[i] = i; // set values for (int i = 0; i<=10; ++i) // print 10 values (???) cout << "v[" << i << "] == " << v[i] << endl; • vector s operator[ ] (subscript operator) reports a bad index (its argument) by throwing a Range_error if you use #include "std_lib_facili5es.h" – The default behavior can differ Excep0ons – for now • For now, just use excep0ons to terminate programs gracefully, like this int main() try { // … } catch (out_of_range&) { // out_of_range excep@ons cerr << "oops – some vector index out of range\n"; } catch (…) { // all other excep@ons cerr << "oops – some excep5on\n"; } A func0on error() • Here is a simple error() func0on as provided in std_lib_facili5es.h • This allows you to print an error message by calling error() • It works by disguising throws, like this: void error(string s) { } // one error string throw run5me_error(s); void error(string s1, string s2) // two error strings { error(s1 + s2); // concatenates } Using error( ) • Example cout << "please enter integer in range [1..10]\n"; int x = -­‐1; // ini@alize with unacceptable value (if possible) cin >> x; if (!cin) // check that cin read an integer error("didn t get a value"); if (x < 1 || 10 < x) // check if value is out of range error("x is out of range"); // if we get this far, we can use x with confidence How to look for errors • When you have wriMen (draged?) a program, it ll have errors (commonly called bugs ) – It ll do something, but not what you expected – How do you find out what it actually does? – How do you correct it? – This process is usually called debugging Debugging • How not to do it while (program doesn t appear to work) { // pseudo code Randomly look at the program for something that looks odd Change it to look beMer } • Key ques0on How would I know if the program actually worked correctly? Program structure • Make the program easy to read so that you have a chance of spozng the bugs – Comment • Explain design ideas – Use meaningful names – Indent • Use a consistent layout • Your IDE tries to help (but it can t do everything) – You are the one responsible – Break code into small func0ons • Try to avoid func0ons longer than a page – Avoid complicated code sequences • Try to avoid nested loops, nested if-­‐statements, etc. (But, obviously, you some0mes need those) – Use library facili0es First get the program to compile • • • • • Is every string literal terminated? cout << "Hello, << name << '\n'; // oops! Is every character literal terminated? cout << "Hello, " << name << '\n; // oops! Is every block terminated? if (a>0) { /* do something */ else { /* do something else */ } // oops! Is every set of parentheses matched? if (a // oops! x = f(y); The compiler generally reports this kind of error late – It doesn t know you didn t mean to close it later First get the program to compile • Is every name declared? – Did you include needed headers? (e.g., std_lib_facili5es.h) • Is every name declared before it s used? – Did you spell all names correctly? int count; char ch; /* … */ ++Count; // oops! /* … */ Cin>>c; // double oops! • Did you terminate each expression statement with a semicolon? x = sqrt(y)+2 // oops! z = x+3; Debugging • Carefully follow the program through the specified sequence of steps – Pretend you re the computer execu0ng the program – Does the output match your expecta0ons? – If there isn t enough output to help, add a few debug output statements cerr << "x == " << x << ", y == " << y << '\n'; • Be very careful – See what the program specifies, not what you think it should say • That s much harder to do than it sounds • for (int i=0; 0<month.size(); ++i) { // oops! • for( int i = 0; i<=max; ++j) { // oops! (twice) Debugging • When you write the program, insert some checks ( sanity checks ) that variables have reasonable values – Func0on argument checks are prominent examples of this if (number_of_elements<0) error("impossible: nega5ve number of elements"); if (largest_reasonable<number_of_elements) error("unexpectedly large number of elements"); if (x<y) error("impossible: x<y"); • Design these checks so that some can be leg in the program even ager you believe it to be correct – It s almost always beMer for a program to stop than to give wrong results Pre-­‐condi0ons • What does a func0on require of its arguments? – Such a requirement is called a pre-­‐condi0on – Some0mes, it s a good idea to check it int area(int length, int width) // calculate area of a rectangle // length and width must be posi@ve { if (length<=0 || width <=0) throw Bad_area(); return length*width; } Post-­‐condi0ons • What must be true when a func0on returns? – Such a requirement is called a post-­‐condi0on int area(int length, int width) // calculate area of a rectangle // length and width must be posi@ve { if (length<=0 || width <=0) throw Bad_area(); // the result must be a posi@ve int that is the area // no variables had their values changed return length*width; } Pre-­‐ and post-­‐condi0ons • • • • • Always think about them If nothing else write them as comments Check them where reasonable Check a lot when you are looking for a bug This can be tricky – How could the post-­‐condi0on for area() fail ager the pre-­‐condi0on succeeded (held)? Example int workOnArray(double[] myArray, int otherInfo) { int i = 0; // complicated calculation of array index i, using otherInfo if (i >= 0 && i < myArray.length) { myArray[i] = 3.14159; return 0; // indicating everything OK } else return -1; // indicating an error } Poten0al Problem • What if workOnArray() needs to return a value (say, a double)? • The C approach: values are returned through addi0onal reference arguments in the method: int workOnArray(double[] myArray, int otherInfo, Double returnValue) • This quickly gets cumbersome. Another Technique: Globals • There are no true global variables in Java, but we fake it all the 0me. • Write a class with sta0c variables! • These are effec0vely available anywhere in a program, and could be used to signal error condi0ons. Faking A Global Variable public class MyGlobal { public static int indexError; MyGlobal() { } // indexError automatically initialized to 0 } void workOnArray(double[] myArray, int otherInfo) { int i = 0; // complicated calculation of array index i, using otherInfo if (i >= 0 && i < myArray.length) { myArray[i] = 3.14159; } else MyGlobal.indexError = -1; } Three Important Issues • Where should the tests be done? – Before the array is indexed into ? – By the array class itself? • Where should the error be reported? – Locally, or further down in the call stack? – Stroustrup says that authors of libraries can t know their user s contexts, so can t know what to do. • Who is responsible for adjudica0ng the error? • Excep0on handling in Java helps with these problems, but doesn t completely solve them. Example class MyExcep0on extends Excep0on { MyExcep0on(String message) { super(message); } } class MyExcep0onThrower { void f() throws MyExcep0on { throw new MyExcep0on("Throwing MyExcep0on"); } } Example, cont public sta0c void main(String[] args){ MyExcep0onThrower t = new MyExcep0onThrower(); try { t.f(); } catch (MyExcep0on e) { e.printStackTrace(); } finally { System.out.println("Done"); } } Some Points • f() must have throws MyExcep0on . Otherwise, compiler will complain. • The compiler insists any call to this method be tested by enclosing it in a try block, or else we get an unreported excep0on error. • If we do include a try block , there has to be a corresponding catch block or finally clause. • When an excep0on is thrown, control goes to the matching catch block. More Points • All of this is true because our excep0on extended the Excep5on class. • If we extend Run5meExcep5on instead, we don t need to say throws, nor include try and catch blocks. • Run5meExcep5ons are special; the Java run0me system takes care of them automa0cally. Excep0ons Always Get Caught public class NeverCaught { sta0c void g() { throw new Run0meExcep0on( From g() ); } sta0c void f() { g(); } public sta0c void main(String[] args) { f(); } } Uncaught Excep0ons • If an excep0on makes it all the way back to main() without being caught, the Java run0me system calls printStackTrace() and exits the program: java.lang.RuntimeException: From g() at NeverCaught.f(NeverCaught.java:5) at NeverCaught.g(NeverCaught.java:8) at NeverCaught.main(NeverCaught.java:11) Exception in thread "main" • You can call printStackTrace() yourself if you want (and it s useful to do it). Look into real example of SmallTalk Excep0on Signal How to throw an exp0on It s a func5on call ? ~~~ Yes Call Stack, Normal Execu0on main() called f() called f() main() main() time g() called g() f() main() g() finished f() main() f() finished main() Call Stack, With Excep0on main() called f() called main() f() main() g() called search f() for handler, exit f() g() f() main() exception thrown, g() has no handler, exit g() f() main() main() search main() for handler, call printStackTrace(), exit main() Catching Any Excep0on • We are always interested in excep0ons that implement the interface Excep5on. • So, a catch block like catch(Excep5on e) { System.out.println( Caught an excep5on ); } will catch any excep0on. • If you have mul0ple catch blocks, this one should be last. Mul0ple Catch Blocks • There may be several possible errors generated by a block of code: try { // try this // and this } catch(YourExcep5on e) { System.out.println( Caught excep5on defined by you ); } catch(Excep5on e) { System.out.println( Caught some other excep5on ); } Rethrowing an Excep0on • Suppose you ve caught an excep0on, and decided you can t recover from it, but perhaps a higher context can. • You can rethrow it: catch(Excep5on e) { System.out.println( An excep5on was caught ); throw e; } • The stack trace remains unchanged if it is caught higher up. Catching, Fixing and Retrying public class Retry { static int i = 0; public void f() { try { g(); } catch(Exception e) { System.out.println("Caught exception, i = " + i); i++; f(); } } void g() throws gException { if (i < 3) { throw new gException(); } else System.out.println("g() is working now"); } This Can Be Dangerous public class Retry { int i = 0; boolean fileIsOpen = false; public void f() { try { if (fileIsOpen) System.out.println("Opening an already opened file!"); else fileIsOpen = true; // i.e., open the file g(); fileIsOpen = false; // i.e., close the file } // file will be left open: Dangerous! What s So Dangerous? • Just close the file in the catch block? Good idea! But, what if some other excep0on were thrown, one that you didn t catch? catch(gException e) { System.out.println("Caught exception, i = " + i); i++; fileIsOpen = false; f(); } finally { fileIsOpen = false; } Excep0on Hierarchies • Excep0ons are classes, so can be in inheritance hierarchies. • The usual polymorphism rules apply. • A handler for a superclass excep0on will catch a subclass excep0on. • This makes it easy to catch groups of excep0ons. • Excep0ons are real objects (created with new), and so can have constructors and data members. Termina0on Vs. Resump0on • Java makes it hard to complete this cycle: – find a problem, – throw an excep0on, – fix the problem in the handler, and – go back to where you leO off. • This is called resump0on . • Java assumes you don t want to go back. • This is called termina0on . What You Can Do • Fix the problem and call the method that caused the excep0on once more. • Patch things up and con0nue without retrying the method. • Calculate some alterna0ve result. • Do what you can in the current context, and rethrow the same excep0on to a higher context. • Do what you can, and throw a different excep0on to a higher context. • Terminate the program (how?). Now let us see real examples • Outline 1) Java 2) Python 3) PHP Excep0on Handling Syntax In Java try Important Points : { 1. try {} block may have one or multiple statements. <statements that can throw excep@ons> } catch(Excep0onType<1> e1) {….} catch(Excep0onType<2> e2) {….} catch(Excep0onType<3> e3) {….} ……………………………….. catch(Excep0onType<N> e4) {….} 2. try{} block may throw a single type of Exception or multiple exceptions. But at a time it can throw only single type of exception. 3. There can be multiple catch() { .. } blocks associated with single try{} block. 4. If try{} block can throw multiple exceptions then user should catch all exceptions. (one catch block for each type of exception) Catching an Excep0on class ED { public sta0c void main(String arhs[]) { int a=10; int b= 5; java.lang.Arithme5cExcep5on: / by zero int c =5; y=1 try { int x = a/(b-­‐c); System.out.println("c="+c); } catch(Arithme0cExcep0on e) { System.out.println(e.toString()); } int y = a/(b+c); System.out.println("y="+y); } } Catching Mul0ple Excep0ons class MED { } java.lang.ArrayIndexOutOfBoundsExcep5on: 0 public sta0c void main(String args[]) Hello This is Excep5on Test { int a[]= {5,10}; try { int b= Integer.parseInt(args[0]); int x = a[b]/(b-­‐a[1]); System.out.println("x="+x); } catch(Arithme0cExcep0on e) { System.out.println(e.toString()); } catch(NumberFormatExcep0on e) { System.out.println(e.toString()); } catch(ArrayIndexOutOfBoundsExcep0on e) { System.out.println(e.toString()); } System.out.println("Hello This is Excep0on Test"); } Nested Try Statements • Try{ } statements can be nested. One try block may contain another try block • In case of nested try blocks, context of that excep5on is pushed onto stack. • Inner try block may/or may not have catch statements associated with it. • If an excep5on is thrown from inner try block then first inner catch statements are matched (if present) . If no match is found then outer try block are matched. If there also no match found then default handler will be invoked. • However, if outer try block throws the excep5on then only outer try blocks are matched. Nested try blocks try { Statement A; Statement B; try { Statement C; Statement D; } catch(CExcep0on e) { …. } catch(DExcep0on e) { …. } } catch(AExcep0on e) { …. } catch(BExcep0on e) { …. } try { Statement A; Statement B; try { Statement C; Statement D; } } catch(AExcep0on e) { …. } catch(BExcep0on e) { …. } catch(CExcep0on e) { …. } catch (DExcep0on e) { …. } Nested try blocks cont… try { Statement A; Statement B; try { Statement C; Statement D; } catch(CException e) catch(DException e) } catch(AException e) { …. catch(BException e) { …. catch(CException e) { …. catch(DException e) { …. { { } } } } …. …. } } Nested try statements Example class NT { Excep0on in thread "main" java.lang.ArrayIndexOutOfBoundsExcep0on: 0 at NT.main(NT.java:8) public sta0c void main(String args[]) { int a[] = { 2,5,6}; // { a[0] = 2, a[1] = 5, a[2] = 6} try // outer try { int b = Integer.parseInt(args[0]); try // inner try { int c[] = { 4,5,6}; // { c[0] = 4, c[1] = 5, c[2] = 6} int d = c[b]/(c[b]-­‐4); } // End of inner try catch(ArrayIndexOutOfBoundsExcep0on e) { System.out.println("Excep0on : "+ e.toString()); System.out.println("By Inner try"); } } catch(Arithme0cExcep0on e) { System.out.println("Excep0on : "+ e.toString()); System.out.println("By Inner try"); } } // End of outer try Throwing Unchecked Excep0on 1. Create an RE which will be thrown by the constructor of the BOX class whenever an axempt will be made to create an RE object. (Any Dimension = 0 or < 0). 2. Create an RE which will be thrown whenever an axempt will be made to create an invalid Triangle object. (In Triangle sum of two sides must be > third side). class RE extends Run0meExcep0on { InvalidBOXExcep0on(String msg) { super(msg); System.out.println("An aMempt is made to create an Invalid BOx object "); } } public class RET { public sta0c void main(String args[]) { Box b1 = new Box(0,0,0); class BOX Box b2 = new Box(10,4,5); { System.out.println( Area of b2: +b2.Area()); private double length; } private double width; } private double height; BOX(double l, double w, double h) throws RE { if( l <=0 || w <= 0 || h <= 0) throw new RE("Invalid BOX Object crea0on"); length = l; An aMempt is made to create an Invalid Box object width = w; height = h; Excep0on in thread "main" RE: Invalid BOX Object } crea0on at Box.<init>(RET.java:27) at RET.main(RET.java:5) Checked Excep0ons • Make your excep5on class extends Excep5on class or any one of its subclass except Rum5meExcep5on. • Checked Excep5ons needs to either caught or informed by use of throws clause • Note down that throw clause is used to throw the excep5on where as throws clause is used to inform that an excep5on is thrown by the method. • Throw clause is used inside method body where as throws clause is used with first line of the method. • Throws clause can be used to inform both type of excep5ons. But in case a method is throwing a unchecked excep5on then it is not compulsory to inform. • In case a method is throwing a checked Excep5on, then it has either to caught the excep5on or informs by using throws clause or it can do both. Use of finally Clause • finally statement can be used to handle an excep0on that is not caught by previous statements. • finally block may be added immediately ager try block or ager the last catch block. • finally block in general used to perform house keeping opera0ons such as closing files or releasing system resources. • Finally block when present is guaranteed to execute regardless of whether an excep0on is thrown or not. • If you want then finally block can be used to handle any excep0on generated within a try block. finally clause Syntax try { ………………….. …………………….. ……………………. } finally { …………….. …………….. ……………. } try { ………………….. …………………….. ……………………. } catch(……….) { ……………. } catch(………..) { ……………. } ….. ….. finally { ………….. ………….. } Example(finally clause) class EX { } Outer Block executed Excep5on in thread "main" java.lang.ArrayIndexOutOfBoundsExcep5on: 0 at EX.main(EX.java:9) public sta0c void main(String args[]) { int a=10; int b = 20; try { int b1=Integer.parseInt(args[0]); int x = a/(a-­‐b1); try { int y = b/(b-­‐b1); } finally { System.out.println("Inner Block executed"); } } finally { System.out.println("Outer Block executed"); } } Crea0ng Hierarchy of Excep0ons 1. We can create our own tree of exception classes. 2. All Exceptions classes in tree are either checked or unchecked depending upon whether the super class is checked or unchecked. InvalidStudentExcep0on InvalidIdNOExcep0on InvalidIdNoYearExcep0on InvalidNameExcep0on InvalidIdNoDesciplineExcep0on Second Example: Python Mul5-­‐paradigm: object-­‐oriented, impera5ve, func5onal, procedural, reflec5ve The main Python implementa0on, named CPython, is wriMen in C mee0ng the C89 standard. It compiles Python programs into intermediate bytecode, which is executed by the virtual machine. CPython is distributed with a large standard library wriMen in a mixture of C and Python. It is available in versions for many pla€orms, including Microsog Windows and most modern Unix-­‐like systems. CPython was intended from almost its very concep0on to be cross-­‐pla€orm. Forming Simple Condi0ons Python Mathematics Meaning < < Less than <= ≤ Less than or equal to == = Equal to >= ≥ Greater than or equal to > > Greater than != ≠ Not equal to Example: Temperature Warnings • The Python if statement is used to implement the decision. • if <condition>: <body> • The body is a sequence of one or more statements indented under the if heading. Lesson objectives 1. Understand how exceptions are generated and handled in Python 2. Use the raise statement to generate exceptions 3. Use the try…except statement to intercept and handle exceptions 4. List the common built-in exceptions What is an exception? • Exceptions are run-time errors • Whenever the interpreter has a problem it notifies the user/ programmer by raising an exception Handling exceptions • By default, the interpreter handles exceptions by stopping the program and printing an error message • However, we can override this behavior by catching the exception Example: nocatch.py fin = open('bad_file') for line in fin: print line fin.close() Traceback (most recent call last): File "nocatch.py", line 2, in <module> open('bad_file') IOError: [Errno 2] No such file or directory: 'bad_file' Example: catch.py try: fin = open('bad_file') for line in fin: print line Something went wrong. fin.close() except: print 'Something went wrong.' Catching specific problems • There are a number of kinds of exceptions, including: – IndexError – EOFError – KeyError – SyntaxError • http://docs.python.org/library/ exceptions.html#bltin-exceptions Example: catch2.py try: fin = open('bad_file') for line in fin: print line Something went wrong. fin.close() except IOError: print 'Something went wrong.' Error handling • Once you ca88tch the error, you need to handle it 1. Perform an alternate action 2. Generate a customized error message and gracefully end the program Raising exceptions • You can also create your own error generating and handling routines by raising an exception • Example: – study147.py line 146 Example 3: PHP impera5ve, object-­‐oriented, procedural, reflec5ve PHP development began in 1994 when the developer Rasmus Lerdorf wrote a series of Common Gateway Interface (CGI) Perl scripts, which he used to maintain his personal homepage. The tools performed tasks such as displaying his résumé and recording his web traffic. He rewrote these scripts in C for performance reasons, extending them to add the ability to work with web forms and to communicate with databases, and called this implementa0on "Personal Home Page/ Forms Interpreter" or PHP/FI. PHP/FI could be used to build simple, dynamic web applica0ons. Understanding Logic and Debugging • Logic refers to the order in which various parts of a program run, or execute • A bug is any error in a program that causes it to func0on incorrectly, because of incorrect syntax or flaws in logic • Debugging refers to the act of tracing and resolving errors in a program Understanding Logic and Debugging (con0nued) • To avoid bugs: – Use good syntax such as ending statements with semicolons – Ini0alize variables when you first declare them – When crea0ng func0ons and for statements, type the opening and closing braces before adding any code to the body of the structure – Include the opening and closing parentheses and correct number of arguments when calling a func0on Syntax Errors • Syntax errors, or parse errors, occur when the scrip0ng engine fails to recognize code • Syntax errors can be caused by: – Incorrect use of PHP code – References to objects, methods, and variables that do not exist – Incorrectly spelled or mistyped words • Syntax errors in compiled languages, such as C ++, are also called compile-­‐5me errors Run-­‐Time Errors • A run-­‐5me error occurs when the PHP scrip0ng engine encounters a problem while a program is execu0ng • Run-­‐0me errors do not necessarily represent PHP language errors • Run-­‐0me errors occur when the scrip0ng engine encounters code that it cannot execute Logic Errors • Logic errors are flaws in a program s design that prevent the program from running as an0cipated for($Count = 10; $Count >= 0; $Count) { if ($Count == 0) echo <p>We have liftoff!</p> ; else echo <p>Liftoff in $Count seconds.</p> ; } Handling and Repor0ng Errors • Parse error messages occur when a PHP script contains a syntax error that prevents your script from running <?php for ($Count = 10; $Count >= 0; —$Count) if ($Count == 0) echo <p>We have liftoff!</p> ; else echo <p>Liftoff in $Count seconds.</p> ; } ?> Handling and Repor0ng Errors (con0nued) PHP parse error message in a Web browser Handling and Repor0ng Errors (con0nued) Web page document illustrating line numbers Handling and Repor0ng Errors (con0nued) • Fatal error messages are raised when a script contains a run-­‐0me error that prevents it from execu0ng function beginCountdown() { for($Count = 10; $Count >= 0; —$Count) { if ($Count == 0) echo <p>We have liftoff!</p> ; else echo <p>Liftoff in $Count seconds.</p> ; } } beginCntdown(); Handling and Repor0ng Errors (con0nued) • Warning messages are raised for run-­‐0me errors that do not prevent a script from execu0ng • A warning message occurs when you aMempt to divide a number by 0 • A warning message occurs if you pass the wrong number of arguments to a func0on Handling and Repor0ng Errors (con0nued) function beginCountdown($Time) { if (!isset($Time)) $Time = 10; for($Count = $Time; $Count >= 0; —$Count) { if ($Count == 0) echo <p>We have liftoff!</p> ; else echo <p>Liftoff in $Count seconds.</p> ; } } beginCountdown(); Handling and Repor0ng Errors (con0nued) PHP warning message in a Web browser Handling and Repor0ng Errors (con0nued) • No5ce messages are raised for poten0al run-­‐0me errors that do not prevent a script from execu0ng • No0ces are raised when a script aMempts to use an undeclared variable $FirstName = Don ; $LastName = Gosselin ; echo <p>Hello, my name is $FirstName $Last.</p> ; Handling and Repor0ng Errors (con0nued) Figure 12-6 PHP notice message in a Web browser Prin0ng Errors to the Web Browser • The php.ini configura0on file contains two direc0ves that determine whether error messages print to a Web browser: – display_errors direc0ve prints script error messages and is assigned a value of On – display_startup_errors direc0ve displays errors that occur when PHP first starts and is assigned a value of Off Sezng the Error Repor0ng Level • The error_reporting direc0ve in the php.ini configura0on file determines which types of error messages PHP should generate • By default, the error_reporting direc0ve is assigned a value of E_ALL, which generates all errors, warnings, and no0ces to the Web browser Sezng the Error Repor0ng Level (con0nued) Table 12-1 Error reporting levels Sezng the Error Repor0ng Level (con0nued) Table 12-1 Error reporting levels (continued) Sezng the Error Repor0ng Level (con0nued) • To generate a combina0on of error levels, separate the levels assigned to the error_reporting direc0ve with the bitwise Or operator (|): error_reporting = E_ERROR | E_PARSE • To specify that the E_ALL error should exclude certain types of messages, separate the levels with bitwise And (&) and Not operators (~) error_reporting = E_ALL &~ E_NOTICE Logging Errors to a File • PHP logs errors to a text file according to: – The error repor0ng level assigned to the error_reporting direc0ve in the php.ini configura0on file – What you set for an individual script with the error_reporting() func0on • The log_errors direc0ve determines whether PHP logs errors to a file and is assigned a default value of Off Logging Errors to a File (con0nued) • The error_log direc0ve iden0fies the text file where PHP will log errors • Assign either a path and filename or syslog to the error_log direc0ve • A value of syslog – On UNIX/Linux systems specifies that PHP should use the syslog protocol to forward the message to the system log file – On Windows systems a value of syslog forwards messages to the Event Log service Wri0ng Custom Error-­‐Handling Func0ons • • Use the set_error_handler() func0on to specify a custom func0on to handle errors Custom error-­‐handling func0ons can only handle the following types of error repor0ng levels: – E_WARNING – E_NOTICE – E_USER_ERROR – E_USER_WARNING – E_USER_NOTICE Wri0ng Custom Error-­‐Handling Func0ons (con0nued) • To print the error message to the screen, you must include echo() statements in the custom error-­‐handling func0on • The switch statement checks the value of the $ErrLevel parameter and then uses echo() statements to print the type of error message Wri0ng Custom Error-­‐Handling Func0ons (con0nued) Figure 12-9 Moving Estimator page after entering nonnumeric values • To log an error with a custom error-­‐handling func0on, call the error_log() func0on Raising Errors with the trigger_error() Func0on • Use the trigger_error() func0on to generate an error in your scripts • The trigger_error() func0on accepts two arguments: – Pass a custom error message as the first argument and – Either the E_USER_ERROR, E_USER_WARNING, or E_USER_NOTICE error repor0ng levels as the second argument The trigger_error() Func0on (con0nued) if (isset($_GET['height']) && isset($_GET['weight'])) { if (!is_numeric($_GET['weight']) || !is_numeric($_GET['height'])) { trigger_error( User did not enter numeric values , E_USER_ERROR); exit(); } } else trigger_error( User did not enter values , E_USER_ERROR); $BodyMass = $_GET['weight'] / ($_GET['height'] * $_GET['height']) * 703; printf( <p>Your body mass index is %d.</p> , $BodyMass); The trigger_error() Func0on (con0nued) Error generated by the trigger_error() function Examining Your Code • An integrated development environment, or IDE, is a sogware applica0on used to develop other sogware applica0ons • The highlight_file() func0on prints a color highlighted version of a file to a Web browser • The highlight_file() func0on prints everything contained in the specified file including HTML elements and text Examining Your Code (con0nued) • By default, the highlight_file() func0on prints each of these elements with the following colors: – Code: blue – Strings: red – Comments: orange – Keywords: green – Page text (default color): black – Background color: white – HTML elements: black Examining Your Code (con0nued) • Change the default highligh0ng colors by modifying the following direc0ves in the php.ini configura0on file: – highlight.string = #DD0000 – highlight.comment = #FF9900 – highlight.keyword = #007700 – highlight.default = #0000BB – highlight.bg = #FFFFFF – highlight.html = #000000 Examining Your Code (con0nued) Figure 12-11 Output of a script with the highlight_file()function Examining Your Code (con0nued) Figure 12-12 Output of the MovingEstimator class with the highlight_file() function Tracing Errors with echo() Statements • Tracing is the examina0on of individual statements in an execu0ng program • The echo() statement provides one of the most useful ways to trace PHP code • Place an echo() method at different points in your program and use it to display the contents of a variable, an array, or the value returned from a func0on Tracing Errors with echo() Statements (con0nued) function calculatePay() { $PayRate = 15; $NumHours = 40; $GrossPay = $PayRate * $NumHours; $FederalTaxes = $GrossPay * .06794; $StateTaxes = $GrossPay * .0476; $SocialSecurity = $GrossPay * .062; $Medicare = $GrossPay * .0145; $NetPay = $GrossPay - $FederalTaxes; $NetPay *= $StateTaxes; $NetPay *= $SocialSecurity; $NetPay *= $Medicare; return number_format($NetPay, 2); } Tracing Errors with echo() Statements (con0nued) function calculatePay() { $PayRate = 15; $NumHours = 40; $GrossPay = $PayRate * $NumHours; echo <p>$GrossPay</p> ; $FederalTaxes = $GrossPay * .06794; $StateTaxes = $GrossPay * .0476; $SocialSecurity = $GrossPay * .062; $Medicare = $GrossPay * .0145; $NetPay = $GrossPay - $FederalTaxes; $NetPay *= $StateTaxes; $NetPay *= $SocialSecurity; $NetPay *= $Medicare; return number_format($NetPay, 2); } Tracing Errors with echo() Statements (con0nued) • • • An alterna0ve to using a single echo() statement is to place mul0ple echo() statements throughout your code to check values as the code executes When using echo() statements to trace bugs, it is helpful to use a driver program A driver program is a simplified, temporary program that is used for tes0ng func0ons and other code Tracing Errors with echo() Statements (con0nued) • A driver program is a PHP program that contains only the code being tested • Stub func5ons are empty func0ons that serve as placeholders (or stubs ) for a program s actual func0ons • A stub func0on returns a hard-­‐coded value that represents the result of the actual func0on Using Comments to Locate Bugs • Another method of loca0ng bugs in a PHP program is to comment out problema0c lines • The cause of an error in a par0cular statement is ogen the result of an error in a preceding line of code Using Comments to Locate Bugs (con0nued) $Amount = 100000; $Percentage = .08; printf( <p>The interest rate or a loan in the amount of $%.2f is %s%%.<br /> , $Amount, $Percentage * 100); $YearlyInterest = $Amount * $Percentage; // printf( The amount of interest for one year is $%.2f.<br /> , $YearlyIntrest); // $MonthlyInterest = $YearlyIntrest / 12; // printf( The amount of interest for one month is $%.2f.<br /> , $MonthlyInterest); // $DailyInterest = $YearlyIntrest / 365; // printf( The amount of interest for one day is $%.2f.</p> , $DailyInterest); Combining Debugging Techniques function calculatePay() { $PayRate = 15; $NumHours = 40; $GrossPay = $PayRate * $NumHours; echo <p>$GrossPay</p> ; // $FederalTaxes = $GrossPay * .06794; // $StateTaxes = $GrossPay * .0476; // $SocialSecurity = $GrossPay * .062; // $Medicare = $GrossPay * .0145; // $NetPay = $GrossPay - $FederalTaxes; // $NetPay *= $StateTaxes; // $NetPay *= $SocialSecurity; // $NetPay *= $Medicare; // return number_format($NetPay, 2); } Analyzing Logic • When you suspect that your code contains logic errors, you must analyze each statement on a case-­‐by-­‐case basis if (!isset($_GET['firstName'])) echo <p>You must enter your first name!</p> ; exit(); echo <p>Welcome to my Web site, . $_GET['firstName'] . ! ; Analyzing Logic (con0nued) • For the code to execute properly, the if statement must include braces as follows: if (!isset($_GET['firstName'])) { echo <p>You must enter your first name!</p> ; exit(); } echo <p>Welcome to my Web site, . $_GET['firstName'] . ! ; Analyzing Logic (con0nued) • The following for statement shows another example of an easily overlooked logic error: for ($Count = 1; $Count < 6; ++$Count); echo $Count<br /> ;