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.

I understand that exception in program means that something unpredictable happened (but not so bad to unavoidably crash the application!). The try-catch-finally sequence makes me sad because the program is harder to read (one more level of curly brackets) and harder to understand (jump from anywhere to catch in case of exception happened, it is deprecated GOTO).

Since we have OOP, I suggest to create proxy class which in case of exception consumes it silently, returns some default value and fires onError event. So if we propagate exception, we have onError call instead, and the two disadvantages mentioned above are solved. See the example in C#:

Standard exception attitude

  class Computer {
    // let's say we need to propagate exception and decide what to do lately
    public int divide(int a, int b) {
      int result = a / b;
      return result;
    }
  }

  class Program {
    public static void Main() {
      Computer c = new Computer();
      try {
        Console.WriteLine(c.divide(1, 0));
      }
      catch(ArithmeticException e) {
        // we are teleported here from the middle of Computer.divide method!
        // do something
      }
    }
  } // three levels of brackets (without namespace) in such trivial example??

onError handler attitude

  class ProxyComputer {
    private Computer c = new Computer();
    // it is not virtual, can not be overriden
    public int divide(int a, int b) {
      // alas, exceptions are standard, but we can stop them in this class
      try {
        return c.divide(a, b);
      }
      catch(ArithmeticException e) {
        this.onError(e);
      }
    }

    protected virtual void onError(Exception e) {
      // do nothing
    }
  }

  class MoreStrictComputer : ProxyComputer {
    protected override void onError(Exception e) {
      // mail to IT department, revert all transactions etc.
      Console.WriteLine("I can't seem to do that");
    }
  }

  class Program {
    public static void Main() {
      ProxyComputer pc = new ProxyComputer();
      MoreStrictComputer msc = new MoreStrictComputer();
      // fires onError instead of exception
      Console.WriteLine(pc.divide(1, 0)); // no problem
      Console.WriteLine(msc.divide(1, 0)); // this time it won't be so easy
    }
  } // only two levels of brackets

Often I see empty (or trivial) catch blocks. This means programmers often consider exception as no problem situation, but with standard exception attitude, they still have to bother with try-catch. The second attitude makes it optional.

So the question is: Which solution would you prefer? Is this some kind of pattern or am I missing something?

Edit As Paul Equis suggests, throw e; should be default onError behavior, not do-nothing silence swalowing.

share|improve this question

migrated from stackoverflow.com Jul 27 '11 at 15:18

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

1  
It looks like your onError() is literally built off exceptions. That kinda defeats the purpose. –  BoltClock Jul 26 '11 at 20:57
    
You mention several times the indentation level associated with try/catch/finally. Well written code normally has only 2-3 levels of indentation. If you're using substantially more than this, then you're not writing good code. Fix the real problem and learn to live with one more level indentation for error checking. –  Stargazer712 Jul 27 '11 at 15:36
add comment

2 Answers 2

up vote 1 down vote accepted

I agree with Paul Equis's answer that exceptions should be preferred, but with a caveat. One major feature of exceptions is that they break control flow. This is usually desirable, but if it isn't then some other pattern might be useful for augmenting the exception system.

For example, suppose you're writing a compiler. Exceptions might not be the best choice here, because throwing an exception stops the compile process. This means that only that first error would be reported. If you want to keep reading the source code in order to try and find more errors (as the C# and VB compilers do), then some other system is needed for reporting errors to the outside world.

The easiest way to take care of that would be saving the exceptions to a collection and then returning it. However, using an OnError delegate might be worthwhile if you want to give the caller an opportunity to give advice on how to proceed after each error. That sounds like an uncommon scenario to me, though. If you're not asking the caller to really micro-manage error handling, then using some flags to specify error-handling behavior would be less fiddly to work with.

share|improve this answer
add comment

I would definitely prefer exceptions to an improvised onError function.

Exceptions are already built into the language. It's the C# defined way for handling unexpected states. Programmers new to your code base will already understand the idea of a try-catch. Some improvised onError handling pattern doesn't really bring any benefit that I can see, and makes your code less standard.

Also, exceptions provide "fail fast" behavior. If you don't catch an exception, it will (typically) result in a crash. This happens automatically, and you have to explicitly swallow an exception for this NOT to happen. But with your onError approach, it's the opposite behavior: all failures are silent unless you listen for them.

This is not a good thing. It increases the distance between where an error is actually caused and where it's noticed (I've heard this concept called "failure distance"). Debugging can be hard enough, and that makes it harder.

share|improve this answer
    
Big +1. I'd also suggest reading the section on exceptions in Framework Design Guidelines. –  TrueWill Jul 26 '11 at 20:44
    
I was inspired by this link. I admit silent swallow approach may not be proper solution, but frankly, often IT IS. If I would be your colleague and you would like to use my code with standard exception behavior, I would define onError handler as throw e; for you. Could it be? –  Jan Turoň Jul 26 '11 at 20:50
    
@JanTuroň Silently swallowing is reasonable sometimes. But should it be the default behavior? And if you made the onErrorHandler just throw the exception, then isn't the solution just a more indirect try-catch? What benefit does this indirection bring? –  Paul Equis Jul 26 '11 at 21:00
    
@PaulEquis: Yes, throw e; is indirect try-catch, but it is optional behavior and this is the point. I admit THIS should be the default behavior, not silent swalowing. Would it be acceptable now? –  Jan Turoň Jul 26 '11 at 21:04
1  
@JanTuroň If you do make that the default behavior, then effectively, users of your class would still have to do a try-catch - which is what you wanted to avoid wasnt it? If you don't make it the default, then you have the problem of silent failures. This is reinventing the wheel. Also, it's very strange to make this behavior optional on the object being called side. The caller of a method typically has more information about what the exception means - it should be the one making the decision whether this "really" should be ignored or not. –  Paul Equis Jul 26 '11 at 21:11
show 3 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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