26
Defensive Programming and Exceptions How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation www.telerik. com

How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Embed Size (px)

Citation preview

Page 1: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Defensive Programming and

ExceptionsHow to Design Error Steady Code

Ivaylo BratoevTelerik

Corporationwww.telerik.com

Page 2: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Defensive ProgrammingUsing Assertions and Exceptions

Correctly

Page 3: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

What is Defensive Programming

Similar to defensive driving – you are never sure what other drivers will do

Expect incorrect input and handle it correctly

Think not only about the usual execution flow, but consider also unusual situations

3

Page 4: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Protecting from Invalid Input

“Garbage in, garbage out.” – NO! Garbage in - nothing out, error

message out or no garbage allowed in

Check the values of all data from external sources (a user, a file, internet, etc.)

4

Page 5: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Protecting from Invalid Input

Check method preconditions – parameters, object state

Check method postconditions – what is guaranteed to the caller

5

string Substring(string str, int startIndex, int length){ REQUIRE(str != NULL); REQUIRE(startIndex >= str.Length); REQUIRE(startIndex + count > str.Lenght);

string result = …

ENSURE(result.Length == length);}

preconditions

main logic

postconditions.

Page 6: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Assertions A statement placed in code that must always be true at that place

Assertions are used during development , they are removed during production compilation

Assertions check for bugs in code 6

void GetAvarageStudentGrade(){ Debug.Assert(studentGrades.Count > 0, “student grades are not initialized”); return studentGrades.Avarage();}

Page 7: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Assertions Use assertions for conditions that should never occur

Use assertions to document assumptions made in code document preconditions and

postconditions

7

private Student GetRegisteredStudent(int id){ Debug.Assert(id > 0); Student student = registeredStudents[id]; Debug.Assert(student.IsRegistered);}

Page 8: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Assertions Failed assertion indicates a fatal error in the program (usually unrecoverable)

Avoid putting executable code in assertions

Won’t be compiled in production. Better:

Assertions should fail loud8

assert PerformAction() : “Could not perform action”

bool actionedPerformed = PerformAction(); assert actionedPerformed : “Could not perform action”

Page 9: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Error Handling Techniques

How do you handle errors that you expect to occur? Depends on the situation.

Examples: Return a neutral value

Return the same answer as the previous time

Log a warning message to a file

Return an error code

Display an error message

Shutdown

Throw an exception

9

Page 10: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Robustness vs Correctness

How will you handle error while calculating single pixel color in a computer game?

How will you handle error while calculating single pixel color in a X-Ray software?

Correctness - never returning an inaccurate result.

Robustness - always trying to do something that will allow the software to keep running. 10

Page 11: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Error Handling Strategy?!?

Choose your error handling strategy and follow it consistently

Strongly consider using exceptions

11

Page 12: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Exceptions Exceptions are a specific means by which code can pass along errors or exceptional events to the code that called it

Methods throw exceptions:

12

public void ReadInput(string input){ if(input == null) { throw new ArgumentNullException(“input”); } …}

Page 13: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Exceptions Use try-catch statement to handle exceptions:

You can use multiple catch blocks to specify handlers for different exceptions.

Not handled exceptions propagate to the caller

13

void playNextTurn() { try { … readInput(input); … } catch(ArgumentNullException e) { console.printLine(“Hello from catch!”); }}

Exception thrown here

Code here won’t be executed

Page 14: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Exceptions Use finally block to execute code even if exception occurs (not supported in C++):

Perfect place to perform cleanup for any resources allocated in the try block.

14

void playNextTurn() { try { … readInput(input); … } finally { console.printLine(“Hello from finally!”); }}

Exception thrown here

Code here is always executed

Page 15: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Exceptions Use exceptions to notify other parts of the program about errors that should not be ignored

Throw an exception only for conditions that are truly exceptional Should I throw an exception when

checking for user name and password?

Don’t use exceptions as control flow mechanisms 15

Page 16: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Exceptions Throw exceptions at the right level of abstraction

16

class Employee { … public TaxId getTaxId() throws EOFException { … }}

class Employee { … public TaxId getTaxId() throws EmployeeDataNotAvailable { … }}

Page 17: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Exceptions Use descriptive error messages

Incorrect example: Example:

Avoid empty catch blocks

17

throw new Exception("Error!");

throw new ArgumentException("The speed should be a number " + "between " + MIN_SPEED + " and " + MAX_SPEED + ".");

try { … // lots of code …} catch(Exception ex){}

Page 18: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Exceptions Always include the exception cause

when throwing a new exception

18

try{ WithdrawMoney(account, amount);}catch (DatabaseException dbex){ throw new WithdrawException(String.Format( "Can not withdraw the amount {0} from acoount {1}", amount, account), dbex);}

We include in the exceptions chain the original source of the

problem.

Page 19: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Exceptions Catch only exceptions that you are capable to process correctly Do not catch all exceptions Incorrect example:

What about OutOfMemoryException?19

try{ ReadSomeFile();}catch{ Console.WriteLine("File not found!");}

Page 20: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Exceptions Have an exception handling strategy for unexpected/unhandled exception: Consider logging (log4net, log4j,

log4cplus). Display to the end users only

messages that they could understand

20

or

Page 21: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Assertions vs. Exceptions

Exceptions are announcements about error condition or unusual event

Inform the caller about error or exceptional event

Can be caught and application can continue working

Assertions are fatal errors Assertions always indicate bugs in the

code

Can not be caught and processed

Application can’t continue in case of failed assertion

When in doubt – throw exception

21

Page 22: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Assertions vs. Exceptions

22

public string Substring(string str, int startIndex, int length){ if (str == null) { throw new NullReferenceException("Str is null."); } if (startIndex >= str.Length) { throw new ArgumentException( "Invalid startIndex:" + startIndex); } if (startIndex + count > str.Length) { throw new ArgumentException("Invalid length:" + length); } … Debug.Assert(result.Length == length);}

Check the input and

preconditions.

Perform the method main logic.

Check the postconditi

ons.

Page 23: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Error Barricades Barricade your program to contain the damage caused by errors Behind the barricade is “safe” area -

data is valid

Validate data crossing the boundary Consider same approach for class design Public methods validate the data

Private methods assume the data is safe

Consider using exceptions for public methods and assertions for private

23

Page 24: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Debugging Aids Don’t automatically apply production constraints to the development version

Be willing to trade speed and resource usage during development

Introduce debugging aids early Make errors obvious during development Asserts should abort the program

Unhandled exceptions should not be hidden

Plan for removing debugging aids

24

Page 25: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Being Defensive About Defensive Programming

Too much defensive programming is not good – strive for balance

How much defensive programming to leave in production code Remove code that results in hard

crashes

Leave in code that checks for important errors

Log errors for your technical support personnel

See that the error messages you leave in are friendly

25

Page 26: How to Design Error Steady Code Ivaylo Bratoev Telerik Corporation

Defensive Programming

Questions? ??

? ? ???

?

?

http://academy.telerik.com