8

They say in java Errors cannot be handled in developer code. But here my code handles a StackOverflowError. What is going on here?

Comments
  • 3
    They probably meant java bytecode errors, I dunno.
  • 5
    Need more context about "they" and "what" exactly was said.
    Your example runtime error is already handled by Java and turned into an exception.
  • 1
  • 1
    @hjk101 but I read another article also, they https://baeldung.com/java-error-cat... said yes an error can ve caught but you need to have a good reason to do so. It makes sense since it both Error and Exception inherit from Throwable. Any Throwable can be used with try catch finally blocks.
  • 0
    @melezorus34 no they explicitly said that's the difference between an Error and an Exception. Which implied all the classes that inherit from Error cannot be handled by an application. Only classes that inherit from Exception can be handled by an application.

    I'm going to research on java bytecode errors, that's new to me.
  • 4
    Yeah, Errors are not intended to be caught, since they are severe programming errors. Exceptions are intended to be caught.

    For example, you shouldn't catch OutOfMemoryError and continue running your program.
  • 0
    @WildOrangutan I am defeated by words yet again.
  • 0
    @KenyanDux basically, corrupt .class files
  • 0
    @WildOrangutan So I guess it's safe to conclude that it's a matter of best practices.
  • 8
    @KenyanDux

    Maybe to give a better worded explanation:

    Exception - a signal that something happened, the developer can decide wether or not they want to recover

    Error - a signal that an severe
    error occured, the developer *can* intervene - but it *might* be impossible to recover from the error

    Fatal error - e.g. the Java process itself terminated, so it is *impossible* to recover from the error

    The problem of your understanding lies in my opinion in a "too literal" interpretation of Error / Unrecoverable Error - which given the resources you had is understandable.

    Think of e.g. the StackOverflowError.

    You catched it, that's right.

    But can you *truly* recover from it? Not really.

    The moment Java overflows the stack due to your recursion, it empties the current stack space for the call between throw and catch. It must empty the stack space to generate free space for the exception handling. After the stack space has been emptied, the exception handling can take place.

    In a very small program like yours it seems trivial to recover, but think of a larger app.

    It's very likely that the exhaustion of the stack space leads to other problems - after all, the stack space doesn't get "fully" emptied, just the recent attempt to write to the stack space got removed.

    So the stack space is *still* close to being full.

    Hence you could *catch the Exception*… but you cannot *fully* recover from it (as you cannot simply empty the full stack space without side effects).

    "Error" mean exactly this: You can catch, but it is highly unlikely you can return to continue the program as if nothing happened at all.

    Most of the time the devil lies in small details ;)
  • 3
    @IntrusionCM Thank you. This totally explains the difference clearly. My understanding was even if you try to catch an Error inside the catch clause it wouldn't have any effect.
  • 6
    @IntrusionCM in theory, if you catch stack overflow outside of the recursion and it reverts the stack to the values of the function that called the recursive function you might do something.

    But if you know the recursion can cause overflow, instead of handling it you should refactor to prevent it to begin with :)
  • 4
    A very valid (and good) question but a similar one on stackoverflow would earn a thousand down votes and tell you to RTFM.

    +1 to this community 😄
  • 1
    @Voxera Yes. That's why I said to think of a larger program. :)
  • 0
    @IntrusionCM *every* throw unwinds the stack without any side effect handing, the only code that can execute in relation to intermediary layers are the destructor of objects only referenced locally, and even those are only called on the next GC run. A Java stack overflow isn't the same as a platform stack overflow, they are often completely recoverable.

    The drawback is that there's no guarantee java will throw a stack overflow error (though most platforms do so very reliably).
  • 2
    @lbfalvy you misunderstood my comment.

    If you have a large program, with dozens of variables etc. and _additionally_ the small snippet @KenyanDux wrote...

    Then the stack space will not consist *only* of the recursive iteration - it will have several other entries.

    The try / catch block will - as you said correctly - only unwind the *relevant* part of the stack space.

    What I tried to point out is, that the stack space still might be close to being full - with variables / ... not belonging to the try / catch clause.

    The remaining context, so to say - context meaning everything else that was added to the stack space previously.

    Meaning that the culprit of the stack overflow could be a total different thing - maybe some entirely different function wasted the stack space, and the recursive function was just "the tip of the iceberg".

    Which is the reason I'm saying you cannot recover from this.

    All you know is that the **last** attempt to write to the stack space has failed, you don't know anything else.

    "Recovering" is the wrong word here.

    If you catch a stack overflow exception, you "ignore" that the last attempt failed and that the stack space might be nearly exhausted and go on.

    Which isn't a solution. Nor a recovery. It's ignoring that something is either wrong in the configuration (stack space too low) or that the runtime contains leaks / bugs
Add Comment