Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

This question already has an answer here:

I have a question about defense programming and handling of exceptions.

Here is a pseudo-code snippet first:

try {
    // do some core logic;
} catch (BadException e) {
    ErrorCode ec = e.getErrorCode();
    if (ec < 10) {
        // handle badException, because its not so bad.
    } else {
        // do not handle and log
    }
}

You see I want to execute some core-logic, that can fail on different conditions and prerequisites. In some of this exceptional cases I want to handle this exception and write some reports and do some other stuff. In all other cases I want to log or rethrow the exception. At my pseudo-code snippet I expressed it with ErrorCodes lower than 10.

Now are in doubt, if this is good coding practice to handle some of that error cases, if I can check for the prerequisites before executing the core-statements.

But if I change the code to check for prerequisites I will end up in code that reads like this here:

try {
    // check prerequisites.
    if (allIsOk) {
        // execute core logic;
    } else {
        // do handle that cases and write back some reports
    }
} catch (BadException e) {
    // do not handle and log
}

But I also don't really like this way, because the try-statement with its core-logic is cluttered up with an if-statement. Should I really blow up the try block with handling of some special parts of BadException in addition to the BadException-Catch-Block?

share|improve this question
    
should your handle badException logic retry the core logic, or return some valid failure code, or what? –  Useless Aug 23 '13 at 12:10
    
The "handle bad Exception"-Block doesn't retry core-logic definitively. But at the moment I wouldn't totaly exclude that some classes deep inside the classes for error handling and writing reports may also throw the BadException. I confess that the real code is far more complex. –  shylynx Aug 23 '13 at 15:00
add comment

migrated from stackoverflow.com Aug 23 '13 at 12:05

This question came from our site for professional and enthusiast programmers.

marked as duplicate by Jim G., GlenH7, Dan Pichelman, Kilian Foth, ChrisF Sep 25 '13 at 11:33

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

2 Answers

The code itself is not good or bad, but the intent can be.

The key point is don't break the responsibility chain between your user, you and what you use.

Defensive programming is "make things working in every case even if badly used". The problem is that you "hide" somebody else bad use in a way you suppose to be correct even not knowing the reason of the bad use.

Different case is you using something in a way you cannot predict if in good or bad way. In that case you catch the exception if you can correct the problem. Essentially you hide to your user you own (not his own) problem being you able to give a proper correct answer.

Things can change a wile if your "user" is a "final user" (not another coder calling your code from his own): in that case -since you cannot expect the final user to correct the code- you must do something to keep its execution safe. But this doesn't change the substance: the exception must be thrown where the problem is noted. The catch must happen where the problem can be corrected (an not hidden).

I -personally- prefer

{
if(!all_is_ok) throw something appropriate.
try { do everithing as it is ok }
catch(my own problems in my own try code)
}

... and let outside coming problem to go outside.

share|improve this answer
    
In my example "AllIsOk" is a value, that is calculated by checking the preconditions and prerequisits. But checking preconditions can also throw the BadException. –  shylynx Aug 23 '13 at 15:08
    
That was exactly what I meant –  Emilio Garavaglia Aug 23 '13 at 17:07
    
What does your last catch-statement mean? Do you really mean, that I should ignore the BadException at all? Or does it mean that I should catch all cases of the BadException I can handle with. But that means that I need two try-catch-Blocks for the BadException. One for checking the precondition and a second one for catching the BadException that comes from the core logic. –  shylynx Aug 23 '13 at 21:26
    
You don't have to cath all what you can handle. Only what you must handle: the cases originated by your own in your function, not the one that are consequence of a bad use of your function. What does this mean in the specific context is something only you can tell. –  Emilio Garavaglia Aug 23 '13 at 21:47
add comment

The try should cover the minimal amount of code. Your example above could probably be written

if (allIsOk) {
    try {
        // check prerequisites.
        // execute core logic; 
    } catch (BadException e) {
        // do not handle and log
    }
}
else {
        // do handle that cases and write back some reports
}

However, probably allIsOk is generated; in which case it would be cleaner to push the core logic into a new function.

// Code to assign allIsOK
if (allIsOk) {
 try {
   executeCoreLogic()
 } catch (BadException e) {
    // log
 }
else {
  // dont bother
}

Also, why you could have BadException and NotSoBadException - Then you could do

try {
    // do some core logic;
} catch (BadException e) {
        // do not handle and log
} catch (NotSoBadException e) {
    // handle it 
}
share|improve this answer
    
As you assumed for the first alternative it isn't what I really search for, because the variable "allIsOk" is calculated by preconditions. The second solution seems smart, but it doesn't reflect, that checking preconditions also throws BadException. And rewrapping it by try-catch isn't a real nice solution. The third solution assumes that we can change the underlying core to throw a NotSoBadException. But core-logic comprises foreign code, we can't touch. Moreover to determine the cases that are not so bad, we need a precond-check, that again needs a try-catch-block for BadException. –  shylynx Aug 23 '13 at 7:05
    
how does this answer the question asked? –  gnat Aug 23 '13 at 12:14
add comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.