defensive programming and exceptions

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

Upload: orly

Post on 09-Feb-2016

28 views

Category:

Documents


1 download

DESCRIPTION

Defensive Programming and Exceptions. How to Design Error Steady Code. Ivaylo Bratoev. Telerik Corporation. www.telerik.com. Defensive Programming. Using Assertions and Exceptions Correctly. What is Defensive Programming. - PowerPoint PPT Presentation

TRANSCRIPT

High-Quality Programming Code Construction

Defensive Programming and ExceptionsHow to Design Error Steady CodeIvaylo Bratoev

Telerik Corporation

www.telerik.com1Defensive ProgrammingUsing Assertions and Exceptions Correctly

What is Defensive ProgrammingSimilar to defensive driving you are never sure what other drivers will do

Expect incorrect input and handle it correctlyThink not only about the usual execution flow, but consider also unusual situations

3

3Protecting from Invalid InputGarbage in, garbage out. NO!Garbage in - nothing out, error message out or no garbage allowed inCheck the values of all data from external sources (a user, a file, internet, etc.)

4

Protecting from Invalid InputCheck method preconditions parameters, object stateCheck method postconditions what is guaranteed to the caller

5string 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);}preconditionsmain logicpostconditions.AssertionsA statement placed in code that must always be true at that place

Assertions are used during development , they are removed during production compilationAssertions check for bugs in code

6void GetAvarageStudentGrade(){ Debug.Assert(studentGrades.Count > 0, student grades are not initialized); return studentGrades.Avarage();}6AssertionsUse assertions for conditions that should never occurUse assertions to document assumptions made in code document preconditions and postconditions

7private Student GetRegisteredStudent(int id){ Debug.Assert(id > 0); Student student = registeredStudents[id]; Debug.Assert(student.IsRegistered);}7AssertionsFailed assertion indicates a fatal error in the program (usually unrecoverable)Avoid putting executable code in assertions

Wont be compiled in production. Better:

Assertions should fail loud

8assert PerformAction() : Could not perform actionbool actionedPerformed = PerformAction(); assert actionedPerformed : Could not perform action8Error Handling TechniquesHow do you handle errors that you expect to occur?Depends on the situation. Examples:Return a neutral valueReturn the same answer as the previous timeLog a warning message to a fileReturn an error codeDisplay an error messageShutdownThrow an exception99Robustness vs CorrectnessHow 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.1010Error Handling Strategy?!?Choose your error handling strategy and follow it consistentlyStrongly consider using exceptions11ExceptionsExceptions are a specific means by which code can pass along errors or exceptional events to the code that called itMethods throw exceptions:12public void ReadInput(string input){ if(input == null) { throw new ArgumentNullException(input); } }12ExceptionsUse try-catch statement to handle exceptions:

You can use multiple catch blocks to specify handlers for different exceptions.Not handled exceptions propagate to the caller13void playNextTurn() { try { readInput(input); } catch(ArgumentNullException e) { console.printLine(Hello from catch!); }}Exception thrown hereCode here wont be executed13ExceptionsUse 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.

14void playNextTurn() { try { readInput(input); } finally { console.printLine(Hello from finally!); }}Exception thrown hereCode here is always executed14ExceptionsUse exceptions to notify other parts of the program about errors that should not be ignoredThrow an exception only for conditions that are truly exceptionalShould I throw an exception when checking for user name and password?Dont use exceptions as control flow mechanisms

1515ExceptionsThrow exceptions at the right level of abstraction

16class Employee { public TaxId getTaxId() throws EOFException { }} class Employee { public TaxId getTaxId() throws EmployeeDataNotAvailable { }} ExceptionsUse descriptive error messagesIncorrect example:Example:

Avoid empty catch blocks17throw 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){}ExceptionsAlways include the exception cause when throwing a new exception18try{ 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.ExceptionsCatch only exceptions that you are capable to process correctlyDo not catch all exceptionsIncorrect example:

What about OutOfMemoryException?19try{ ReadSomeFile();}catch{ Console.WriteLine("File not found!");}19ExceptionsHave an exception handling strategy for unexpected/unhandled exception:Consider logging (log4net, log4j, log4cplus).Display to the end users only messages that they could understand20

or20Assertions vs. ExceptionsExceptions are announcements about error condition or unusual eventInform the caller about error or exceptional eventCan be caught and application can continue workingAssertions are fatal errorsAssertions always indicate bugs in the codeCan not be caught and processedApplication cant continue in case of failed assertionWhen in doubt throw exception2121Assertions vs. Exceptions22public 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 postconditions.Error BarricadesBarricade your program to contain the damage caused by errors Behind the barricade is safe area - data is validValidate data crossing the boundaryConsider same approach for class designPublic methods validate the dataPrivate methods assume the data is safeConsider using exceptions for public methods and assertions for private

23Debugging AidsDont automatically apply production constraints to the development versionBe willing to trade speed and resource usage during developmentIntroduce debugging aids earlyMake errors obvious during developmentAsserts should abort the programUnhandled exceptions should not be hiddenPlan for removing debugging aids

24In debug mode, Microsoft Word contains code in the idle loop that checks the integrity of the Document object every few seconds. This helps to detect data corruption quickly, and makes for easier error diagnosis.24Being Defensive About Defensive ProgrammingToo much defensive programming is not good strive for balanceHow much defensive programming to leave in production codeRemove code that results in hard crashesLeave in code that checks for important errorsLog errors for your technical support personnelSee that the error messages you leave in are friendly25Defensive ProgrammingQuestions???????????http://academy.telerik.com