ArsTechnica

Log in Register

Technology Lab / Information Technology

Are there reasons for returning exception objects instead of throwing them?

There are a few situations where not throwing an exception is appropriate.

Stack Exchange
This Q&A; is part of a weekly series of posts highlighting common questions encountered by technophiles and answered by users at Stack Exchange, a free, community-powered network of 100+ Q&A; sites.

stakx asked:

This question is intended to apply to any OO programming language that supports exception handling; I am using C# for illustrative purposes only.

Exceptions are usually intended to be raised when an problem happens that the code cannot immediately handle, which is then caught in a catch clause in a different location (usually an outer stack frame).

My question is this: are there any legitimate situations where exceptions are not thrown and caught, but simply returned from a method and then passed around as error objects?

This question came up for me because .NET 4's System.IObserver.OnError method suggests just that: exceptions being passed around as error objects.

Let's look at another scenario, validation. Let's say I am following conventional wisdom and that I am therefore distinguishing between an error object type IValidationError and a separate exception type ValidationException that is used to report unexpected errors:

    partial interface IValidationError { }

    abstract partial class ValidationException : System.Exception
    {
        public abstract IValidationError[] ValidationErrors { get; }
    }

(The System.Component.DataAnnotations namespace does something quite similar.)

These types could be employed as follows:

    partial interface IFoo { }  // an immutable type

    partial interface IFooBuilder  // mutable counterpart to prepare instances of above type
    {
        bool IsValid(out IValidationError[] validationErrors);  // true if no validation error occurs
        IFoo Build();  // throws ValidationException if !IsValid(…)
    }

Now I am wondering, could I not simplify the above to this:



    partial class ValidationError : System.Exception { }  // = IValidationError + ValidationException

    partial interface IFoo { }  // (unchanged)

    partial interface IFooBuilder
    {
        bool IsValid(out ValidationError[] validationErrors);
        IFoo Build();  // may throw ValidationError or sth. like AggregateException
    }

So what are the advantages and disadvantages of these two differing approaches?

See the original question here.

What’s in an exception?

Mathew Foscarini answers (18 votes):

Are there any legitimate situations where exceptions are not thrown and caught, but simply returned from a method and then passed around as error objects?

If it is never thrown then it's not an exception. It is an object derived from an Exception class, though it does not follow the behavior. Calling it an Exception is purely semantics at this point, but I see nothing wrong with not throwing it. From my perspective, not throwing an exception is the exact same thing as an inner-function catching it and preventing it from propagating.

Is it valid for a function to return exception objects?

Absolutely. Here is a short list of examples where this may be appropriate:

  • An exception factory.
  • A context object that reports if there was a previous error as a ready to use exception.
  • A function that keeps a previously caught exception.
  • A third-party API that creates an exception of an inner type.

Is not throwing it bad?

Throwing an exception is kind of like: "Go to jail. Do not pass Go!" in the board game Monopoly. It tells a compiler to jump over all source code up to the catch without executing any of that source code. It doesn't have anything to do with errors, reporting or stopping bugs. I like to think of throwing an exception as a "super return" statement for a function. It returns execution of the code to somewhere much higher up than the original caller.

The important thing here is to understand that the true value of exceptions is in the try/catch pattern, and not the instantiation of the exception object. The exception object is just a state message.

In your question you seem to be confusing the usage of these two things: a jumping to a handler of the exception, and the error state the exception represents. Just because you took an error state and wrapped it in an exception does not mean you are following the try/catch pattern or its benefits.

Related: "If exceptions should only be used in exceptional cases, how do I know if my case is exceptional?"

For example

Philipp answers (42 votes):

Returning exceptions instead of throwing them can make semantical sense when you have a helper-method for analyzing the situation and returning an appropriate exception which is then thrown by the caller (you could call this an "exception factory"). Throwing an exception in this error analyzer function would mean that something went wrong during the analysis itself, while returning an exception means that the kind of error was analyzed successfully.

One possible use-case could be a function which turns HTTP response codes into exceptions:

    Exception analyzeHttpError(int errorCode) {
        if (errorCode < 400) {
             throw new NotAnErrorException();
        }
        switch (errorCode) {
            case 403:
                 return new ForbiddenException();
            case 404:
                 return new NotFoundException();
            case 500:
                 return new InternalServerErrorException();
            …
            default:
                 throw new UnknownHttpErrorCodeException(errorCode);
         }
    }

Note that throwing an exception means that the method was used wrong or had an internal error, while returning an exception means that the error code was identified successfully.

Find more answers or leave your own at the original post. See more Q&A like this at Programmers, a site for conceptual programming questions at Stack Exchange. And of course, feel free to login and ask your own question.

Expand full story

24 Reader Comments

  1. Exceptions don't (typically) work like the first commenter stated.

    Exceptions are "expensive" compared to return codes* and passed in error flags** because they allocate exception data and walk the stack until they find an error handler. The compiler (typically) shouldn't do anything special besides standard optimizations to dictate the code paths taken. Honestly it couldn't in a lot of cases. If it did, loading a library at runtime would ruin its plans. No matter how your code is loaded the stack will be a consistent vector for handler resolution.

    Personally I like error flags when I expect there to be problems (i.e. a vendor's API is terrible and I'm always going to check for an error) and exceptions when dealing with the unexpected, like network access issues.

    Ex:
    *Return code:

    int doSomething(){
    ...
    if (somethingBadHappened()){
    return 1;
    }
    ...
    //Success!
    return 0;
    }

    ** Error Flag:

    //C/C++
    void doSomething(myErrorStruct *foo){
    //C#
    void doSomething(ref myErrorStruct foo){
    ...
    if (somethingBadHappened()){
    foo->error = kSOMETHINGBAD;
    foo.error = ErrorPossibilities.SomethingBad;
    return;
    }
    ...
    //Success!
    return;
    }
    11 posts | registered
  2. Is it me or does System.ComponentModel.DataAnnotations.ValidationException look like the devil's work?

    Last edited by WaveRunner on Sat Oct 19, 2013 2:29 pm

    1295 posts | registered
  3. Moto7451 wrote:
    Exceptions don't (typically) work like the first commenter stated.

    Exceptions are "expensive" compared to return codes* and passed in error flags** because they allocate exception data and walk the stack until they find an error handler. The compiler (typically) shouldn't do anything special besides standard optimizations to dictate the code paths taken. Honestly it couldn't in a lot of cases. If it did, loading a library at runtime would ruin its plans. No matter how your code is loaded the stack will be a consistent vector for handler resolution.

    Depends on the language and the JIT really. Yes you're generally right, but fun fact: Some early benchmark code in Java used ArrayOutOfBoundsExceptions to iterate through arrays and other funny things.

    Which - you guessed it - leads to some rather interesting optimizations for this kind of thing in HotSpot..
    1325 posts | registered
  4. Think of exceptions as heart attacks. In this analogy, throws are helicopters and catch clauses are emergency clinics. If you do that you will never ask yourself again whether or not to throw, whether to return an exception/error-code or not.

    If you embed a try/catch in every function, especially if you nest them, you are complicating the code unnecessarily. What's the point of having 100 helicopters hovering just in case a person gets a heart attack. Keep exceptions for truly exceptional circumstances. Anywhere else you're better off simply returning an error code or an exception, whichever is more convenient, and deal with as part of the normal flow.
    587 posts | registered
  5. Moto7451 wrote:
    Exceptions don't (typically) work like the first commenter stated.

    Exceptions are "expensive" compared to return codes* and passed in error flags** because they allocate exception data and walk the stack until they find an error handler. The compiler (typically) shouldn't do anything special besides standard optimizations to dictate the code paths taken. Honestly it couldn't in a lot of cases. If it did, loading a library at runtime would ruin its plans. No matter how your code is loaded the stack will be a consistent vector for handler resolution.

    Personally I like error flags when I expect there to be problems (i.e. a vendor's API is terrible and I'm always going to check for an error) and exceptions when dealing with the unexpected, like network access issues.

    Ex:
    *Return code:

    int doSomething(){
    ...
    if (somethingBadHappened()){
    return 1;
    }
    ...
    //Success!
    return 0;
    }

    ** Error Flag:

    //C/C++
    void doSomething(myErrorStruct *foo){
    //C#
    void doSomething(ref myErrorStruct foo){
    ...
    if (somethingBadHappened()){
    foo->error = kSOMETHINGBAD;
    foo.error = ErrorPossibilities.SomethingBad;
    return;
    }
    ...
    //Success!
    return;
    }


    I don't know how this guy got voted down. Exceptions causes a context switch, which costs thousands of clock cycles just in processing, plus lost cycles due to cache thrashing.

    Exceptions should not be used except for exceptional situations that rarely occur.
    2048 posts | registered
  6. Yep, I think it's perfectly valid to return an exception. For example if you try to download something from the internet but there is no internet connection... you definitely should not throw an exception but it's perfectly reasonable to create an exception object describing what happened and return it.

    It might not be appropriate in some languages however. For example in Objective-C there is an "Exception" class and an "Error" class. They're both pretty much the same, except an "Error" cannot be thrown, rather it is intended to be used the way exceptions are described in this question.

    Think of exceptions as heart attacks. In this analogy, throws are helicopters and catch clauses are emergency clinics. If you do that you will never ask yourself again whether or not to throw, whether to return an exception/error-code or not.

    I think it's far easier to think of exceptions as exceptions, instead of some kind of crazy metaphor. They're nowhere near as complicated as a heart attack and bunch of helicopters.

    A metaphor should make things simpler, not even more complicated.
    730 posts | registered
  7. Bengie25 wrote:
    Moto7451 wrote:
    Exceptions don't (typically) work like the first commenter stated.

    Exceptions are "expensive" compared to return codes* and passed in error flags** because they allocate exception data and walk the stack until they find an error handler. The compiler (typically) shouldn't do anything special besides standard optimizations to dictate the code paths taken. Honestly it couldn't in a lot of cases. If it did, loading a library at runtime would ruin its plans. No matter how your code is loaded the stack will be a consistent vector for handler resolution.

    Personally I like error flags when I expect there to be problems (i.e. a vendor's API is terrible and I'm always going to check for an error) and exceptions when dealing with the unexpected, like network access issues.

    Ex:
    *Return code:

    int doSomething(){
    ...
    if (somethingBadHappened()){
    return 1;
    }
    ...
    //Success!
    return 0;
    }

    ** Error Flag:

    //C/C++
    void doSomething(myErrorStruct *foo){
    //C#
    void doSomething(ref myErrorStruct foo){
    ...
    if (somethingBadHappened()){
    foo->error = kSOMETHINGBAD;
    foo.error = ErrorPossibilities.SomethingBad;
    return;
    }
    ...
    //Success!
    return;
    }


    I don't know how this guy got voted down. Exceptions causes a context switch, which costs thousands of clock cycles just in processing, plus lost cycles due to cache thrashing.

    Exceptions should not be used except for exceptional situations that rarely occur.

    I didn't vote him down, but I don't think the issue he's raising applies to this discussion at all.

    Exceptions only cause a context switch when you throw them. An exception that never gets thrown does not cost any clock cycles and is a clean way to describe an error condition.

    Also, premature optimisation is the root of all evil. Do not worry about the speed of an exception unless you have first demonstrated that your use of them is slow.

    The real reason not to use exceptions has nothing to do with performance (in 99% of cases) and everything to do with the fact it completely breaks the normal flow of code, allowing you to jump multiple levels up the execution stack instead of going up the stack one at a time giving each item a chance to clean up along the way.
    730 posts | registered
  8. Exceptions sounded like a good idea at first. In practice, they're really hard to work with. If you have a factory that makes objects that's part of a model that's embedded in a container (like a web application) that's running in a federated server instance, and you get an exception ... then what? If you have a network error, what do you do about it? If your database connection doesn't work, then what? So the idea of catching an exception comes down to who catches it and what do they do with it?

    And I think when you see "abstract partial class" that's an indication that overengineering is creeping in. To solve complexity, make it more complex?
    387 posts | registered
  9. Quote:
    Are there reasons for returning exception objects instead of throwing them?


    No.
    1414 posts | registered
  10. Bengie25 wrote:
    I don't know how this guy got voted down. Exceptions causes a context switch, which costs thousands of clock cycles just in processing, plus lost cycles due to cache thrashing.

    While *he* was absolutely right, your own claim is completely bogus. Why do you think you'd need a context switch to throw/catch an exception?

    Trencher93 wrote:
    Exceptions sounded like a good idea at first. In practice, they're really hard to work with. If you have a factory that makes objects that's part of a model that's embedded in a container (like a web application) that's running in a federated server instance, and you get an exception ... then what? If you have a network error, what do you do about it? If your database connection doesn't work, then what? So the idea of catching an exception comes down to who catches it and what do they do with it?

    Exactly the same thing you'd do if you would get an error code back?
    1325 posts | registered
  11. My view has always been that exceptions should be thrown when something happens that is known to be possible but which should not occur under normal circumstances. Examples include the network connection going down during a file transfer, or a coding error that leads to an invalid array index being used.

    As has been pointed out, throwing an exception is an expensive process and therefore should not be used in cases where there is a good chance that he exception will be thrown often. For example, validating user input could use the exception mechanism, but only if the outcome was to stop processing further input. But processing data within a loop should not throw exceptions unless it causes the loop to be exited.

    As for the original question, objects representing exceptional outcomes are comparable to return codes and should be used in similar situations. But they should not be confused with exception objects, and should probably not be termed such (e.g., throw Exception objects, return Result objects).
    180 posts | registered
  12. Agreed that exceptions should be used only in exceptional circumstances that shouldn't occur. However sometimes when dealing with com or third party libraries there is no way to test if some internal object that you're about to request is actually set and so you end up using exception handling just to get round that limitation.

    Typically if a method that I'm writing can fail in a non-exceptional way I try to return a null value instead of the expected type and test for null where the method is called to see what to do instead.

    I also agree that passing around exception objects isn't exception handling, rather it is error handling using an exception object as a container for the error. Personally I think that passing around of exception objects should only be done for factory methods or logging methods. In all other situations I can think of you're either forcing the code to use object return types where another type should be used (thus adding unnecessary and expensive type checking to all callers). Or you should be throwing the exception and having finally blocks for any cleanup you may need to do on the way.
    246 posts | registered
  13. Perhaps not returning an error but sort of the same.

    When coding asynchronous code you sort of need to provide the callback some way of knowing that shit went wrong. For example node.js cb(err, res) pattern. So yes.
    8 posts | registered
  14. In some cases, like handling batch request calls, it makes a lot of sense for the batching interface to catch all the exceptions and store them up in a structure, and then return the structure afterwards (or do something with its contents to decide whether the batch is invalid or the like).
    390 posts | registered
  15. Exceptions when used correctly are fine, if something has gone wrong you can't recover from why would you not throw an exception. I don't understand the problem people have with them. Is the cost worse than unwinding the stack when something goes wrong and all the noise in the code that entails. The code noise to handle it instead is just a source of bugs

    That said you can use something like the Exception Monad and pipeline commands so that the pipeline halts on an exception. This is cheaper than throwing while still using exceptions to carry the error report. Best of both worlds. It does require a more functional mindset though.
    11 posts | registered
  16. Quote:
    …


    An encoding issue on Ars? I am disappointed.

    (The original is ellipses: …)
    72 posts | registered
  17. The expensiveness of exceptions is implementation specific. For example, I understand pypy jit can trace away simple cases like StopIteration.

    More important, I think, is the cost in code complexity. Returning an error is a trivial thing to understand: the caller gets it. Throwing an exception, OTOH, can take execution any number of levels up the call hierarchy. The kind of programmer who being given a hammer sees all things as nails should not be let near exceptions.

    As for the question itself, if you take it literally the answer is 'obviously'. Not just factories, but even constructors are technically returning exception objects. However, a special case is whether it's ever a good idea to return an exception instead of throwing to indicate an exception/error in the function. That seems likely to confuse readers, better to return some other error object instead.
    260 posts | registered
  18. Trencher93 wrote:
    Exceptions sounded like a good idea at first. In practice, they're really hard to work with. If you have a factory that makes objects that's part of a model that's embedded in a container (like a web application) that's running in a federated server instance, and you get an exception ... then what? If you have a network error, what do you do about it? If your database connection doesn't work, then what? So the idea of catching an exception comes down to who catches it and what do they do with it?


    I don't think it's that complicated. If you come across something after which it's not possible to continue executing the rest of your code, whatever it is, throw an exception. Then make sure you have a centralized handler for all exceptions further up the callstack, that usually just logs it. And if there's exceptions you want to treat differently, have a handler further down the callstack for those.

    Quote:
    Returning an error is a trivial thing to understand: the caller gets it.


    And you are now relying on the caller to actually do something with that return code. What if he ignores the return value and simply continues on? That might be a valid decision, but with exceptions, that becomes a conscious choice: you have to catch the exception, a conscious act. With returning codes or errors, you have now built in a dependency on the infallibility of the developer.

    I really, really, really don't see the value in returning errors as part of any API. It might be a valid choice within a very narrow scope (like the exception factory example) but never part of the public or even internal interface of your code if you write in a language that supports exceptions.

    Quote:
    Throwing an exception, OTOH, can take execution any number of levels up the call hierarchy.


    Exactly. That's the point. Your program has reached a point at which execution can no longer continue, so we have to unwind the stack back to where it's possible to continue (so where there's an exception handler) or if that's not possible, terminate the program. The thrower of the exception generally doesn't even have to concern himself with where it's caught, he just encountered something that made it impossible for him to continue executing the rest of the code he wrote, so he needs to bail. Where it gets caught, should generally not concern him.

    EDIT: In fact, as I wrote the above, I realized that returning errors instead of throwing exceptions is a recurring problem in product I work on. I have a webservice and if an error occurs, the response to the webservice contains an error object. There's no real choice, you can't throw an exception in that scenario. But I am reliant on the caller of the webservice to check if the response contains an exception (response.Exception != null) and 9 out of 10 times, they don't. The right thing for them to do is in the part that actually performs the HTTP request to my webservice, add a centralized check for the existence of the exception object and if it exists, throw an exception.
    241 posts | registered
  19. And you are now relying on the caller to actually do something with that return code. What if he ignores the return value and simply continues on? That might be a valid decision, but with exceptions, that becomes a conscious choice: you have to catch the exception, a conscious act. With returning codes or errors, you have now built in a dependency on the infallibility of the developer.


    Actually, it depends on the language you are using...

    If you are using C#, you don't have to catch anything. Uncaught exceptions will just crash your application.
    If you are using Java, then yes, the compiler will throw an error if you don't catch exceptions.

    So if using C#, if you don't catch exceptions, you're in the same position if you returned NULL, and didn't check the value, and tried to dereference it.. Both will crash your app.

    This brings up the other problem with exceptions... In Java, you have to declare what your function throws. So when you write your app, and you use somebody elses code, you know what to expect, because you can see what it can throw...

    With C#, you don't have that... So you have to read the documentation, and hope the developer stuck to the documentation, otherwise you don't have the foggiest idea what could be thrown.

    That's why I think a lot of C# guys, just return error codes, because it's status quo, and is reminiscent of returning an HRESULT.
    1323 posts | registered
  20. a_v_s wrote:
    And you are now relying on the caller to actually do something with that return code. What if he ignores the return value and simply continues on? That might be a valid decision, but with exceptions, that becomes a conscious choice: you have to catch the exception, a conscious act. With returning codes or errors, you have now built in a dependency on the infallibility of the developer.


    Actually, it depends on the language you are using...

    If you are using C#, you don't have to catch anything. Uncaught exceptions will just crash your application.
    If you are using Java, then yes, the compiler will throw an error if you don't catch exceptions.

    So if using C#, if you don't catch exceptions, you're in the same position if you returned NULL, and didn't check the value, and tried to dereference it.. Both will crash your app.


    That's not what I mean though. If you throw an exception, the stack will unwind to the nearest applicable handler, meaning that you can't possibly erroneously continue. Usually you'll have a central handler, but if you don't, yeah the program crashes. But that's not important. What's important that you weren't allowed to continue executing the rest of your code, unless you made the conscious decision to catch it. There is no possible way to accidentally ignore a failure of something. With an error code, those guarantees don't exist. Say I called a method to save something to my database (say something important like a payment), the database save failed because it timed out. Then you return an error code/object which I happily completely ignore and then I'll display a nice message to my customer saying "payment succeeded. Thank you for your purchase!" even though it didn't succeed at all. With exceptions, that simply can't happen. If the exception crashes the program/request, that's fine, it means you weren't able to do anything meaningful with the exception, the only logical thing is to crash. Crashing or not crashing is not important, that you are not allowed to continue by accident is the important bit.

    Java's checked exceptions are a nightmare, though.

    Quote:
    That's why I think a lot of C# guys, just return error codes, because it's status quo, and is reminiscent of returning an HRESULT.


    As a C# guy, I'll never ever merge a pull request that returns an error code unless there's a damn good reason for it.

    And honestly, I can't think of any popular .NET library that works with error codes. There's FluentValidation that returns a ValidationResult, but a validation error does not necessarily result in an exception. That's up to the caller of the library.
    241 posts | registered
  21. And honestly, I can't think of any popular .NET library that works with error codes. There's FluentValidation that returns a ValidationResult, but a validation error does not necessarily result in an exception. That's up to the caller of the library.


    There are lots of libraries that return enumerations for error codes. Tho most of the ones I've seen are also wrappers for C/C++ libraries. The ones that weren't wrappers, usually had an enumeration as part of the async handlers to propagate errors that were encountered.

    As far as .NET libraries... If you look at the I/O libraries, particularly the async ones... Some of them in the AsyncResult handler, the EndRead method will succeed and return 0 on a graceful close, while some will throw an IOException on the EndRead method call on a graceful close.

    Last edited by a_v_s on Sun Oct 20, 2013 1:44 am

    1323 posts | registered
  22. There is no possible way to accidentally ignore a failure of something.


    Sure there is... I've seen it frequently with people that forget to check their code for re-entrancy. I've seen people catch an exception that they were expecting to be thrown by the method they were calling, without realizing that method they called made a callback into their code somewhere, which happened to call some API that could throw that same exception but they forgot to put an exception handler for it, and it ends up getting caught somewhere else, where the context was different so the failure path was wrong, and the error ends up getting dropped.

    For example, let say someone calls some method, and tries to catch an IOException. For the method they are calling, this exception means there was a graceful close, so they gracefully shut down, and continue... However, they didn't know that this method happened to make a callback into their code somewhere, where it was doing something else, and made it's own IO calls for something, but forgot to catch any IOExceptions, and it ends up propagating to the other try/catch block, where in this context, an IOException means a graceful close, even tho in the context it was actually thrown, it was not a graceful close, so the app treats it as a graceful close, and continues, even tho this was the wrong course of action.

    Granted, this is also sloppy design, but I'm not trying to argue this is good design, just refuting your point that it's impossible to accidentally ignore a failure.
    1323 posts | registered
  23. a_v_s wrote:
    There is no possible way to accidentally ignore a failure of something.


    Sure there is... I've seen it frequently with people that forget to check their code for re-entrancy. I've seen people catch an exception that they were expecting to be thrown by the method they were calling, without realizing that method they called made a callback into their code somewhere, which happened to call some API that could throw that same exception but they forgot to put an exception handler for it, and it ends up getting caught somewhere else, where the context was different so the failure path was wrong, and the error ends up getting dropped.

    For example, let say someone calls some method, and tries to catch an IOException. For the method they are calling, this exception means there was a graceful close, so they gracefully shut down, and continue... However, they didn't know that this method happened to make a callback into their code somewhere, where it was doing something else, and made it's own IO calls for something, but forgot to catch any IOExceptions, and it ends up propagating to the other try/catch block, where in this context, an IOException means a graceful close, even tho in the context it was actually thrown, it was not a graceful close, so the app treats it as a graceful close, and continues, even tho this was the wrong course of action.

    Granted, this is also sloppy design, but I'm not trying to argue this is good design, just refuting your point that it's impossible to accidentally ignore a failure.


    This is why proper logging of exceptions is so important as the logging (in dotnet anyway) should show where the exception occurred. IMO exceptions should always be logged even if debug logging has been switched off. That way you can review the logs for frequent exceptions and try to trace the causes.
    246 posts | registered
  24. Quote:
    Returning an error is a trivial thing to understand: the caller gets it.


    And you are now relying on the caller to actually do something with that return code. What if he ignores the return value and simply continues on? That might be a valid decision, but with exceptions, that becomes a conscious choice: you have to catch the exception, a conscious act. With returning codes or errors, you have now built in a dependency on the infallibility of the developer.


    IMO it's the same with both. You don't need to actively do anything to ignore the return value or the exception. The only difference is what happens if you do that. When ignoring return values you continue on as if nothing is wrong, which may or may not work. When ignoring exceptions your app by default blows up. Which is better depends...

    (It's different if you are developing a library: any exceptions you ignore can still be caught by the caller, while the caller can do nothing about the return values you ignore.)

    Quote:
    Throwing an exception, OTOH, can take execution any number of levels up the call hierarchy.


    Exactly. That's the point. Your program has reached a point at which execution can no longer continue, so we have to unwind the stack back to where it's possible to continue (so where there's an exception handler) or if that's not possible, terminate the program. The thrower of the exception generally doesn't even have to concern himself with where it's caught, he just encountered something that made it impossible for him to continue executing the rest of the code he wrote, so he needs to bail. Where it gets caught, should generally not concern him.


    Oh, I'm not saying they aren't a good tool. They are often easy to use even. However, they do make it more difficult for a reader of the code to see what happens when an exception is thrown: finding the callers of a function is usually trivial, recursively finding all the places up the call chain where the exception might be caught is not.
    260 posts | registered

You must to comment.

You May Also Like

    Need to register for a new account?

    If you don't have an account yet it's free and easy.

    Register