Top Banner
Exceptions • Problems with error reporting so far – Either ignored exceptions or terminated program on first error. – Error handling and regular code mixed – User interface and computation code mixed
51

Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Dec 20, 2015

Download

Documents

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Exceptions

• Problems with error reporting so far– Either ignored exceptions or terminated

program on first error.– Error handling and regular code mixed– User interface and computation code mixed

Page 2: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Argument Printer

package main;

public class AnArgPrinter{

public static void main(String args[]) {

System.out.println(args[0]);

}

}Exception will be reported to the user

Page 3: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Error checkif (args.length == 0 ) {

System.out.println("Did not specify the argument to be printed. Terminating program.");

System.exit(-1);

} else {

System.out.println(args[0]);

}Regular and error code mixed together

Page 4: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Exception handler

try {

System.out.println(args[0]);

}

catch (ArrayIndexOutOfBoundsException e) {

System.out.println("Did not specify the argument to be printed. Terminating program.");

System.exit(-1);

} Regular and error code separate

Page 5: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Printing multiple arguments: main

public static void main (String args[]) {

echoLines(numberOfInputLines(args));

}

Page 6: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

numberOfInputLines

static int numberOfInputLines(String[] args) { try { return Integer.parseInt(args[0]); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Did not enter an

argument.") return 0; }}

UI mixed in computation method

Arbitrary legal value returned, program not halted

Page 7: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

echoLines

static void echoLines (int numberOfInputLines) { try { for (int inputNum = 0; inputNum <

numberOfInputLines; inputNum++) System.out.println(inputStream.readLine()); } catch (IOException e) { System.out.println("Did not input " +

numberOfInputLines + " input stringsbefore input was closed. "); System.exit(-1); }}

Decision to halt without full context

Page 8: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Moral: Separate error detection and handling

• In this example– Let echoLines() and numberOfInputLines() not

do the error handling.– All they do is error reporting– Main does error handling and associated UI

Page 9: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Error code solution

• Pass back error codes to main– Works for procedures as we can make it return

value instead of void– Does not work for functions as error code may

be legal return value• Integer function returning all possible integer values

Page 10: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Global variable solution

• Store error codes in common variables– Does not work when there are multiple calls to

the same method• A call may overwrite value written by another call

– Variable may accessed by other methods sharing its scope

Page 11: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Exception propagation

• Java lets exceptions be “returned instead of regular values.

• These propagate through call chain until some method handles them

Page 12: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Propagating echoLines

static void echoLines (int numberOfInputLines) throws IOException {

for (int inputNum = 0; inputNum < numberOfInputLines; inputNum++)

System.out.println(inputStream.readLine());

}

Tells caller that passing it the

exception

Page 13: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Propagating numberOfInputLines

static int numberOfInputLines(String[] args) throws ArrayIndexOutOfBoundsException {

return Integer.parseInt(args[0]);

}

}

Page 14: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Handling in main

public static void main (String args[]) { try { echoLines(numberOfInputLines(args)); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Did not enter an argument. Assuming a

single input line.”); echoLines(1); } catch (IOException e) { System.out.println("Did not input the correct number of input

strings before input was closed. "); } }

Has contextIO exception not

caught

Page 15: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Handling in mainpublic static void main (String args[]) {

try {

echoLines(numberOfInputLines(args));

} catch (ArrayIndexOutOfBoundsException e) { System.out.println("Did not enter an argument. Assuming a single input

line.”);

try {

echoLines(1);

} catch (IOException ioe) {

System.out.println("Did not input the one input string, which is the default in case of missing argument, before input was closed. ");

}

} catch (IOException e) { System.out.println("Did not input the correct number of input strings

before input was closed. ");

}

}

Must be different names

Page 16: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Passing the buck in main

public static void main (String args[]) throws IOException, ArrayIndexOutOfBoundsException {

echoLines(numberOfInputLines(args));

}

Bad idea as interpreter’s messages may be meaningless to the user

Page 17: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Omitting IOException in throws clause

static void echoLines (int numberOfInputLines) {

for (int inputNum = 0; inputNum < numberOfInputLines; inputNum++) System.out.println(inputStream.readLine());

}

Java complains IOException neither handled nor declared

Caller does not know what it must handle

Page 18: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Omitting ArrayIndexOutOfBoundsException in

throws clausestatic int numberOfInputLines(String[] args) {

return Integer.parseInt(args[0]);

}

}

No complaints from Java

Page 19: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Java has two kinds of exceptions

• Unchecked exceptions– Called “runtime”, but all exceptions are

runtime!– Subclasses of RunTimeException

• E.g. ArrayIndexOutofBoundsException

– Uncaught exceptions need not be declared

• Checked exceptions– Uncaught exceptions must be declared

• Rationale for division?

Page 20: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Misleading header

static void safeArrayIndexer throws ArrayIndexOutOfBoundsException () {

String args[] = {“hello”, “goodbye”};

System.out.println(args[1]);

}• Array index does not

imply exception• Java cannot tell the

difference

Array index out of bounds guaranteed to not happen

Page 21: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Reasons for exceptions

• User error– Programmer cannot prevent it

– Should be acked• Analogous to specifying class methods in interface – a form of

comments checked by Java

• Internal error– Programmer can prevent

– A method that can be erroneous probably is not really erroneous

– Acking is probably misleading

Page 22: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Justification of Java Rules

Java rules justified if:

• Checked (Non-runtime) exceptions = user errors

• Unchecked (runtime) exceptions = internal errors

Page 23: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Checked vs. Unchecked

• Unchecked– No rules

• Checked1. uncaught in method body => acknowledged in method header2. unacknowledged in method header => caught in method body

(from 1) 3. unacknowledged in interface method-header => unacknowledged

in class method-header4. unacknowledged in interface method-header => caught in method

body (from 2 and 3)5. Interface can be used to force method implementations to catch

exceptions

Page 24: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Interface/Class relationshippublic interface StringEnumeration {

...

public String nextElement();

}

public class AnInputStreamScanner implements StringEnumeration {

...

public String nextElement() {

try {

return inputStream.readLine();

} catch (IOException e) {

return “”;

}

}

}

unacknowledged in interface method-header => caught in method body

Page 25: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Interface/Class relationshippublic interface StringEnumeration {

...

public String nextElement();

}

public class AnInputStreamScanner implements StringEnumeration {

...

public String nextElement() throws IOException{

return inputStream.readLine();

}

}

unacknowledged in interface method-header => caught in method body

Page 26: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Interface/Class relationshippublic interface StringEnumeration {

...

public String nextElement();

}

public class AnInputStreamScanner implements StringEnumeration {

...

public String nextElement() throws java.util.NoSuchElementException {

if (!hasMoreElements()) throw new java.util.NoSuchElementException();

return inputStream.readLine();

}

}Unchecked, as most users will call

hasMoreElements before nextElement()

Page 27: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Standard Enumeration interfacepackage java.util;public interface Enumeration {

...public Object nextElement();

}

public class AnInputStreamScanner implements java.util.Enumeration{

...

public Object nextElement() throws java.util.NoSuchElementException {

if (!hasMoreElements()) throw new java.util.NoSuchElementException();

return inputStream.readLine();

}

} Good idea to throw this exception when no more elements

Page 28: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Throwing multiple exceptionspublic interface StringEnumeration {

...

public String nextElement() throws java.io.IOException;

}

public class AnInputStreamScanner implements StringEnumeration {

...

public String nextElement() throws java.util.NoSuchElementException, java.io.IOException {

if (!hasMoreElements()) throw new java.util.NoSuchElementException();

return inputStream.readLine();

}

}

When no more elements

When next element erroneous because of user error (e.g. scanning rules

violated)

Page 29: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Printing debugging information

catch (ArrayIndexOutOfBoundsException e) {

System.out.println(e);

}

catch (ArrayIndexOutOfBoundsException e) {

e.printStackTrace();

}

e.getMessage()

Stack when exception is thrown

Page 30: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Printing stack

Stack that existed when exception was thrown

Page 31: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Justification of Java Rules

Java rules justified if:

• Checked (Non-runtime) exceptions = user errors

• Unchecked (runtime) exceptions = internal errors

Page 32: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Problems with Java rules

Unchecked exceptions can be caused by user error

static int numberOfInputLines(String[] args) {

return Integer.parseInt(args[0]);

}

}

Page 33: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Approach 1: Voluntarily list exception

static int numberOfInputLines(String[] args) throws ArrayIndexOutOfBoundsException {

return Integer.parseInt(args[0]);

}

}

No way to force every caller that does not handle it to ack it.

Page 34: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Approach 2: Convert to existing checked exception

static int numberOfInputLines(String[] args) throws IOException {

try {

return Integer.parseInt(args[0]);

} catch (ArrayIndexOutOfBoundsException e) {

throw new IOException (“First argument missing”);

} Exception object thrown explicitly message

Page 35: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Approach 3: Convert to new checked exception

static int numberOfInputLines(String[] args) throws IOException {

try {

return Integer.parseInt(args[0]);

} catch (ArrayIndexOutOfBoundsException e) {

throw new AMissingArgumentException(“First argument missing”);

} Our own exception

Page 36: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Creating Exception Class

public class AMissingArgumentException extends java.io.IOException {

public AMissingArgumentException(String message) {

super(message);

}

} No interface!Not adding any methods

Page 37: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Checked vs. Unchecked Programmer-defined Exceptions

• An exception class must be subclass of existing exception classes

• Subclass of RunTimeException is unchecked

• All other exceptions are checked

• Java does not define exception interfaces

• Neither can we as a result

Page 38: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Handling programmer-defined exceptions

try {

echoLines(numberOfInputLines(args));

} catch (AMissingArgumentException e) {

System.out.println(e);

System.exit(-1);

} catch (IOException e) {

System.out.println(e);

System.exit(-1);

}

Page 39: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Removing Code Duplicationtry {

echoLines(numberOfInputLines(args));

} catch (IOException e) {

System.out.println(e);

System.exit(-1);

}

AMissingArgumentException is subclass

Page 40: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Removing Code Duplicationtry {

echoLines(numberOfInputLines(args));

} catch (IOException e) {

System.out.println(e);

System.exit(-1);

} catch (AMissingArgumentException e) {

System.out.println(e);

} AMissingArgumentException processed hereList exception subclass

before superclass Unreachable block

Page 41: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Interface/Class relationshippublic interface StringEnumeration {

public boolean hasMoreElements();public String nextElement() throws Exception;

}

public class AnInputStreamScanner implements StringEnumeration {

...

public String nextElement() throws IOException{

return inputStream.readLine();

}

}

Stronger advertisement

allowed

void print (StringEnumeration stringEnumeration) {

try {

while (stringEnumeration.hasMoreElements())

System.out.println(stringEnumeration.nextElement());

} catch (Exception e) {…}

}Can handle IOException

Page 42: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Interface/Class relationshippublic interface StringEnumeration {

...public String nextElement() throws IOException;

}

public class AnInputStreamScanner implements StringEnumeration {

...

public String nextElement() {

try {

return inputStream.readLine();

} catch (IOException e) {

return “”;

}

}

Stronger advertisement

allowed void print (StringEnumeration stringEnumeration) {

try {

while (stringEnumeration.hasMoreElements())

System.out.println(stringEnumeration.nextElement());

} catch (IOException e) {…}

}

Page 43: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Interface/Class relationshippublic interface StringEnumeration {

public boolean hasMoreElements();public String nextElement() throws IOException;

}

public class AnInputStreamScanner implements StringEnumeration {

...

public String nextElement() throws Exception {

return inputStream.readLine() + … ;

}

}

Weaker advertisement not

allowed

void print (StringEnumeration stringEnumeration) {

try {

while (stringEnumeration.hasMoreElements())

System.out.println(stringEnumeration.nextElement());

} catch (IOException e) {…}

}Cannot handle Exception

Page 44: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Interface/Class relationshippublic interface StringEnumeration {

public boolean hasMoreElements();public String nextElement();

}

public class AnInputStreamScanner implements StringEnumeration {

...

public String nextElement() throws IOException{

return inputStream.readLine();

}

}

Weaker advertisement not

allowed

void print (StringEnumeration stringEnumeration) {

while (stringEnumeration.hasMoreElements())

System.out.println(stringEnumeration.nextElement());

} Not handling IOException

Page 45: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Implementation/body relationshippublic interface StringEnumeration {

public boolean hasMoreElements();public String nextElement() throws Exception;

}

public class AnInputStreamScanner implements StringEnumeration {

...

public String nextElement() throws Exception {

return inputStream.readLine();

}

}

void print (StringEnumeration stringEnumeration) {

try {

while (stringEnumeration.hasMoreElements())

System.out.println(stringEnumeration.nextElement());

} catch (Exception e) {…}

}Can handle IOException

Stronger advertisement

allowed

Page 46: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Implementation/body relationshippublic interface StringEnumeration {

public boolean hasMoreElements();public String nextElement() throws AMissingArgumentException;

}

public class AnInputStreamScanner implements StringEnumeration {

...

public String nextElement() throws AMissingArgumentException {

return inputStream.readLine();

}

}

void print (StringEnumeration stringEnumeration) {

try {

while (stringEnumeration.hasMoreElements())

System.out.println(stringEnumeration.nextElement());

} catch (AMissingArgumentException e) {…}

}Cannot handle IOException

Weaker advertisement not

allowed

Page 47: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Exceptions in initialization

• int numberOfInputLines = numberOfInputLines()– Checked exception not being handled or acknowledged

• Do initialization in method– public static void main (String args) {

try {

numberOfInputLines = numberOfInputLines()

} catch (AMissingArgumentException e) {

}

}

Page 48: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

IS-A Rule for Exceptions

• Exception of type T1 uncaught in method body => exception of type T2, where T1 IS-A T2, acknowledged in method header

• Exception of type T1 acknowledged in interface method-header => exception of type T2, where T2 IS-A T1, acknowledged in class method-header

• Should overstate rather than understate bad side effects– Dizziness, headache

• If you are bad, you should not say you are good.– People will be disappointed

• If you are good, you can say you are bad– Don’t let people down

Page 49: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Catching expected events

try {

for (;;) {

String s = inputStream.readLine();

process(s);

}

} catch (IOException e) { };

Using EOF to terminate the loopBad style, exception handler processes expected

eventmore efficient: no extra if

check

Page 50: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Intra-method propagationwhile (enumeration.hasMoreElements())

try {

System.out.println((String) enumeration.nextElement());

} catch (ClassCastException e) { e.printStackTrace());}

try {

while (enumeration.hasMoreElements())

System.out.println((String) enumeration.nextElement());

} catch (ClassCastException e) {e.printStackTrace());}

println terminated and exception propagated to enclosing loop, which

is also terminated, and catch executed

Println terminated, catch executed, and loop continues

Page 51: Exceptions Problems with error reporting so far –Either ignored exceptions or terminated program on first error. –Error handling and regular code mixed.

Terminating loop vs. statement

• Independent errors can be collected– Scanning: 5 ( 2 } 1

• Dependent errors cannot be: – Parsing: 5 + 2 4 / - 2