user1883212
user1883212

Reputation: 7859

call stack: catch vs. throws

When to use "catch" and when to use "throws"?

try {
    //stuff
} 
catch (MyException me) {
    //stuff
}

versus

public void doSomething() throws MyException {
    //stuff
}

In the case of "throws", where to place my catch along the call stack?

Main
    ----- Function 1
        ----- Function 2
            ----- Function 3 (generate exception)

If I propagate the exception from function 3 to function 2, why shouldn't function 2 do the same? So at the end I would end up managing all the exceptions in the "main" and I think it's not a go0d practice to put all the code inside a try block, isn't it?

So what's the logical way to choose between "catch" and "throws"? And in the second case, where should I place my catch in the call stack?

Upvotes: 3

Views: 247

Answers (3)

Fritz
Fritz

Reputation: 10055

If you're going for a throw - catch approach to handle errors, then the actual error handling must be done by the component with the responsibility of doing so, in particular because this allows you to encapsulate the logic where it belongs.

The exception is catched by a certain class who knows what to do with it, and the course of action that must be taken. In some particular cases you can rethrow an exception by wrapping it in another one (setting the exception as its cause). Take any ORM as an example, any low level exception is wrapped in, for example, a PersistenceException that can have a SQLSyntaxException as its cause.

throws comes into play if you don't have the proper tools to manage the exception in a certain context and you want to propagate it to a higher layer/tier where it can be properly managed.

Let me put a "big picture example":

  1. Save entity to database
  2. Communication error
  3. Exception is thrown, so your persistence object must handle it.
  4. You catch it, wrap it and rethrow it as one of your own exceptions (I'm against letting persistence exceptions propagate to higher layers... but that's just me).
  5. the persistence throws an exception that's catched by the model.
  6. The model retries the operation.
  7. Another failure (same wrap + throw).
  8. The model notifies the failure and elevates a report to the view. This is what I meant by being catched by the one who "knows" what to do.
  9. The view displays "No saving today, sorry" to the user.

The example contains both throw and catch cases, I hope it helps to clarify.

Upvotes: 0

Leo Izen
Leo Izen

Reputation: 4289

You should declare that a method throws a checked exception whenever it's necessary for the method's caller to catch it or pass it on. You should catch an exception whenever you are ready to handle that exception right then and there.

For example, if you're writing a program with a graphical interface that also has a core that reads from a file, the core classes are unequipped to tell the user there was an error, that's the graphical interface's job. So methods such as getSomethingFromFile() in a core program might throw IOException. If the graphical interface calls getSomethingFromFile() and determines there's a read error, the graphical interface can then display a dialog to the user, so it is ready then and there to catch the exception. In this case, the getSomethingFromFile() call should be enclosed in try/catch.

Upvotes: 0

yshavit
yshavit

Reputation: 43391

They're basically inverse of each other. throws means that a function is allowed to throw an exception; catch means that a block (the try) block expects that an exception might get thrown, and is prepared to handle it.

To take the ball metaphor, a pitcher throws an exception that the catcher expects. The catcher catches the ball and handles it somehow. (Well, maybe the metaphor is a bit off, since the catcher usually handles the ball by throwing it back to the pitcher. :) ) Here, the pitcher is a method, and the catcher is a try-catch-[finally] block.

Upvotes: 2

Related Questions