I know that Error is Throwable (so it can be handled) and Error handling isn't best practice but suppose we have a requirement to catch all Error.
It is possible in general? I mean what about Errors which can appear in daemon threads? They will crash jvm and I won't know about it.
And can I miss Error even if I surround main(String... args) with try-catch?
You can catch the uncaught exceptions via Thread.setUncaughtExceptionHandler()
Set the default handler invoked when a thread abruptly terminates due
to an uncaught exception, and no other handler has been defined for
that thread.
Uncaught exception handling is controlled first by the thread, then by
the thread's ThreadGroup object and finally by the default uncaught
exception handler. If the thread does not have an explicit uncaught
exception handler set, and the thread's thread group (including parent
thread groups) does not specialize its uncaughtException method, then
the default handler's uncaughtException method will be invoked.
Whether that's a good idea is another question (!). It may be that you simply want to clear up resources, shut down connections etc., log the issue and/or alert the user. If you do have critical issues like OutOfMemoryErrors then there's little else you can do.
An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions.
Now, since Error does indeed extends Throwable, it is possible to catch 'any' error via a simple try-catch statement as follows:
try{
//Error causing code here...
}catch(Error e){
//Handle error here...
}
However, since errors come in different forms, a thrown error may or may not be accompanied by a change in the jvm's behaviour to cause unexpected results.
Consider the Error OutOfMemoryError. When this Error is thrown, the JVM's heap may be so full that any type of handling code results in another OutOfMemoryError being thrown, voiding any attempt of recovery.
Furthermore, even when running on the "primary" thread (the one the application starts in), a error could cause a JVM to crash before every throwing a Error.
Looking at the description of VirtualMachineError (of which Errors such as OutOfMemoryError, StackOverflowError, InternalError, etc are subclasses of) we see:
Thrown to indicate that the Java Virtual Machine is broken or has run out of resources necessary for it to continue operating.
The javadoc itself states that the jvm no longer can continue operation normally much less allow a programmer to just 'handle' them away.
On the other hand, errors such as UnsatisfiedLinkError generally do not cause a problem with the jvm straight away and can generally be handled (whether this is good practice is debatable). I personally have once used a structure that involves handling a UnsatisfiedLinkError to determine the correct library to load for JNI.
Now, can all errors be handled? Theoretically yes, if we assume that the JVM can continue operation perfectly despite claiming to have failed fatally... With that in regard, practically only a small subset of errors are handleable. Whether or not these small subset of errors should be handled is also a highly controversial topic.
You can handle exceptions, but you can't handle errors.
Related
I'm trying to understand difference between error and exception but it looks same thing and on Oracle Official tutorials I read this line.
Checked exceptions are subject to the Catch or Specify Requirement.
All exceptions are checked exceptions, except for those indicated by
Error, RuntimeException, and their subclasses.
Now about I'm thinking it's same. But after searching more I found some difference as theoretical that.
Exception: are recoverable
Errors: not recoverable.
Exception Example:
try{
read file
}
catch(FileNotFoundException e){
// how I can recover here? can i create that file?
// I think we can just make log file to continue or exit.
}
Error Example:
try{
try to locate memory
}
catch(MemoryError e){
// I think we can just make log file to continue or exit.
}
Edited
I'm asking about recover-able and non-recoverable.
Error, as you already figured out, means you are in serious trouble. In a catch block you might be able to do something like logging, but basically that's it.
Non-recoverable exceptions are mostly runtime exceptions like NullPointerException. They are usually the result of some missed checks in the program code. Therefore the solution is normally to fix the code.
A recoverable exception is something that you know beforehand can happen and take certain measures. Think of a web application that calls some backend service. That service may or may not be available which can cause the execution of the operation to fail. Therefore you have a checked exception, in this case most likely a custom exception that you throw, and then handle it in the front end code in a manner where you tell the user, sorry backend service xy is down, try again later or contact support.
Recoverable does not mean that the application can do something to resolve the cause of the exception, though there may be cases where this is possible.
All classes that inherit from class Exception but not directly or indirectly from class RuntimeException are considered to be checked exceptions.Such exceptions are typically caused by conditions that are not under the control of the program.
Example
in file processing, the program can’t open a file if it does not
exist.
Recoverable
So It is very easy to know that if a file does not exists so you dont need to open that file hence that is recoverable
All exception types that are direct or indirect subclasses of RuntimeException (package java.lang) are unchecked exceptions. These are typically caused by defects in program’s code.
Example
ArrayIndexOutOfBoundsExceptions
ArithmeticExceptions
Error
Unrecoverable
So thatswhy program can not recover from these kind of errors or exceptions
Unrecoverable errors are the ones that put the application in an undefined state, like a broken database connection or a closed port, you may handle the error and continue to execute but it would not make sense. Modern languages like Rust and Go use the name panic for errors of these nature, to make the distinction clear. Best action to take is logging the error, if it is possible, and exiting the application.
A recoverable errors are the ones we can handle gracefully, like division by zero or validation errors. It is something expected and the resulting behavior is covered in the language spec. Yes, application behaves erratic when that a recoverable error happens but we can contain it or work around it.
The Object Throwable has 2 childs : Exception and Error.
All Exceptions are recoverable and all Errors are non-recoverable.
All Exceptions are recoverable because you can catch them and let your program continue its execution.
However all Errors , even when you add them to a catch block, will cause the abrupt termination of your program.
Examples of Errors: StackOverflowError, OutOfMemoryError,..
Remark : Checked and unchecked Exceptions are childs of Exception so recoverable.
Surprisingly google didn't describe any catastrophic scenarios my twisted mind craved for.
Anywhere I read, catching errors is discouraged. Basic rule seems to be that if your application produced error, it's already dead, beyond saving. So if you catch errors in your main function, does your program turn into zombie?
How can even error be caught if the program is already collapsing? Can catching errors do something real bad? Which errors are worst and which are sometimes caught? Could you describe a little test case that can produce the errors (like really produce them, not just throw them) so that I can see that they do if I catch them and ignore them?
Not much happens except that the thrown object is caught. Your process can be in a bad place, though, depending on what caused the error.
A StackOverflowError is pretty undramatic to catch - it's thrown when the maximum stack depth is exceeded, and since it then starts popping the call stack, it's no longer a problem (unless you try calling the offending method again).
class SO {
static int stackOverflow(){ return stackOverflow(); }
public static void main(String... args) {
try {
stackOverflow();
} catch (StackOverflowError e) {
System.out.println("Oh well, life goes on.");
}
}
}
Other errors, like OutOfMemoryError, are somewhat more problematic - there will still be too much memory used after it's been thrown. Some are directly fatal, like ClassFormatError, which means that you're trying to load a broken class file (and it's usually thrown in places where you can't catch it).
Other Errors are somewhere inbetween. AssertionError, for example, is thrown when a programmer-defined condition (like assert answer == 42;) isn't met, but only if you've enabled assertions.
Long story short, though: If you're catching specific errors, you're probably doing the wrong thing (unless you really know what you're doing!). If you're running a server app and want it to keep running, you're probably better of letting the current thread or process die and have it restarted by some kind of monitor.
Catching an Exception or Error is not a good idea, unless;
you can do something useful with it.
as a last resort to ensure it is logged correctly or in a submitted Runnable to an ExecutorService. In this case catching Throwable may be desirable.
Nothing terrible will happen if you catch an Error, however you can't pretend it didn't happen either (i.e. you can't just continue as if it didn't matter)
Note: not catching an error can be a bad thing for multi-threaded applications. This is because an uncaught error only closes the current thread. If there are multiple threads, they will keep running if at least one is not a daemon This can leave a program running but in a bad state.
I ask what happens.
Nothing special, you catch it and you can deal with it or log it.
Are you talking about catching Exceptions? There are two types of Exceptions checked and unchecked. The reason to catch an Exception as simple as catching a programmer defined Exception which enables the user to reenter the data. This normally applies to checked Exceptions.
Unchecked Exceptions cannot be recovered from and you might ask why catch them at all? Perhaps the developer wants to catch it to log the conditions which caused the Exception and to better troubleshoot the issue.
Here is an article discussing them both.
http://tutorials.jenkov.com/java-exception-handling/checked-or-unchecked-exceptions.html
We have a piece of code for reading from queue
while(true){
try {
message = readMessageFromQueue();
processMesage(message); //Writes into DB and some other operation
}catch(Exception e) {
log the exception
}
}
Now there are ten threads which are spawned using executor service with the aim of running forever. However we have noticed after sometime we deploy(it can be 10-15 days or month) the number of thread is getting reduced(Write per second is also decreasing because of that).
The question is should we catch Error or only exception in the code which we want to run forever like this and is catching Exception can cause this problem ?
Yes, it's better to catch a Throwable there, not just Exception. Depending on your processing you might get, for example, a StackOverflowError that will kill your thread without logging. You might not be able to recover from it, but at least you can debug the problem latter.
From what I understand, you're asking if it is okay to catch by general Exception versus specific exceptions, like ArrayOutOfBoundsException. So, I guess my answer come down to whatever you prefer. You can catch by Exception, which isn't usually advised because you should always know what your code is doing and thus what could go wrong, but it does accomplish your tasks. Now, the reason you should catch by specific exceptions is that you can have different methods of handling different errors. Maybe the way you are handling the error isn't universally applicable to all errors, so when the thread sees an exception it isn't designed to expect, it crashes leaving you with one less thread.
I prefer catching specific exceptions of I can do something gracefully with that failure (like retry or do some default behavior). But if an exception means the program can't continue at all regardless, than catching the most generic exception and terminating is fine.
catching Exception is a "shotgun" approach to exception handling - "Whatever exception you will throw, I will catch it!".
catching a specific, ideally custom Exception is preferred mainly because you know where that exception is thrown, and you can gracefully handle that exception, or do some methods specifically for a certain exception. Therefore gives you more control of your application.
hope this helps.
There are lot of posts on java.lang.Error saying it should not be caught. My question is if it should not be caugth the what is the use of it. Since it is Throwable so we can catch it in try catch. I read some posts like only in some situation it should be caught, how to know these situations.
In short i want to know what can go wrong when i catch Error. What is process behind it. Why they have made Error and its Subclasses? If my app is not supposed to catch them then what catches them? Why my code cannot handle this caught Error? If i simply catch one Error and write some handling code in Catch block, won't that code run?
An Error (especially a subclass of VirtualMachineError) indicates that the JVM has encountered an internal issue - one that means that its internal state may no longer be consistent. If you catch an Error and attempt to recover, future behaviour is undefined. The reason that errors are Throwable is so they can be thrown - eg you may do it your self for errors in a native library that can't be recovered from (eg the library could have written to JVM memory, or corrupted its internal static state). The same stack walking and stack trace producing machinery is used in the case of all Throwables - it would be silly to have another mechanism to do the same thing.
Most errors in the JVM that are not VirtualMachineErrors are situations where a native library could have corrupted its static state - eg AWTError, ZipError.
However there are some rare cases where catching an Error is sane: AssertionError in a testing framework, and LinkageError where you have to deal with the absence / presence of different versions of libraries at runtime. This is a pretty rare requirement and may be better handled through reflection.
All rules have exceptions (except this one).
Even if everybody say you should not, there are plenty of cases where it's totally appropriate to catch those java.lang.Error. The logic behind the rule was: "do not try to continue running your application after a fatal condition was detected". You therefore must be careful before doing something after such an error is thrown. It is possible that the system might not be able to continue its task afterward.
It might be OK for a servlet to catch OutOfMemoryError, log the error and destroy the session. Maybe the problem was with that precise session. Destroying it would restore the memory and allow other users to continue using the system. However, you should have a mechanism to track those errors in real-time in order to:
Fix programming errors
(AssertionError, StackOverflowError)
Fix configuration errors
(UnsatisfiedLinkError)
Correct JVM sizing parameters (OutOfMemoryError)
This kind of handling should be done very "high" in the call stack (i.e. near the main()), where the main loop (or equivalent) is performed. I think it's not a good practice to catch Error in deep code, you should at least rethrow the error in those cases.
Similar question already answered here - When to catch java.lang.Error?
Basically, you should never attempt to catch it as its thrown on fairly serious issues like when your thread has dead for some reason, and is not recoverable.
There are however sometimes the need to catch the error when dealing with the framework itself as stated in the above URL.
I'm trying to learn more about basic Java and the different types of Throwables, can someone let me know the differences between Exceptions and Errors?
Errors should not be caught or handled (except in the rarest of cases). Exceptions are the bread and butter of exception handling. The Javadoc explains it well:
An Error is a subclass of Throwable that indicates serious problems that a
reasonable application should not try to catch. Most such errors are abnormal
conditions.
Look at a few of the subclasses of Error, taking some of their JavaDoc comments:
AnnotationFormatError - Thrown when the annotation parser attempts to read an annotation from a class file and determines that the annotation is malformed.
AssertionError - Thrown to indicate that an assertion has failed.
LinkageError - Subclasses of LinkageError indicate that a class has some dependency on another class; however, the latter class has incompatibly changed after the compilation of the former class.
VirtualMachineError - Thrown to indicate that the Java Virtual Machine is broken or has run out of resources necessary for it to continue operating.
There are really three important subcategories of Throwable:
Error - Something severe enough has gone wrong the most applications should crash rather than try to handle the problem,
Unchecked Exception (aka RuntimeException) - Very often a programming error such as a NullPointerException or an illegal argument. Applications can sometimes handle or recover from this Throwable category -- or at least catch it at the Thread's run() method, log the complaint, and continue running.
Checked Exception (aka Everything else) - Applications are expected to be able to catch and meaningfully do something with the rest, such as FileNotFoundException and TimeoutException...
This slide showing Java's exception hierarchy by #georgios-gousios concisely explains the differences between Errors and Exceptions in Java.
Errors tend to signal the end of your application as you know it. It typically cannot be recovered from and should cause your VM to exit. Catching them should not be done except to possibly log or display and appropriate message before exiting.
Example:
OutOfMemoryError - Not much you can do as your program can no longer run.
Exceptions are often recoverable and even when not, they generally just mean an attempted operation failed, but your program can still carry on.
Example:
IllegalArgumentException - Passed invalid data to a method so that method call failed, but it does not affect future operations.
These are simplistic examples, and there is another wealth of information on just Exceptions alone.
Errors -
Errors in java are of type java.lang.Error.
All errors in java are unchecked type.
Errors happen at run time. They will not be known to compiler.
It is impossible to recover from errors.
Errors are mostly caused by the environment in which application is running.
Examples : java.lang.StackOverflowError, java.lang.OutOfMemoryError
Exceptions -
Exceptions in java are of type java.lang.Exception.
Exceptions include both checked as well as unchecked type.
Checked exceptions are known to compiler where as unchecked exceptions are not known to compiler because they occur at run time.
You can recover from exceptions by handling them through try-catch blocks.
Exceptions are mainly caused by the application itself.
Examples : Checked Exceptions : SQLException, IOException
Unchecked Exceptions : ArrayIndexOutOfBoundException, ClassCastException, NullPointerException
further reading : http://javaconceptoftheday.com/difference-between-error-vs-exception-in-java/
Sun puts it best:
An Error is a subclass of Throwable
that indicates serious problems that a
reasonable application should not try
to catch.
The description of the Error class is quite clear:
An Error is a subclass of Throwable
that indicates serious problems that a
reasonable application should not try
to catch. Most such errors are
abnormal conditions. The ThreadDeath
error, though a "normal" condition, is
also a subclass of Error because most
applications should not try to catch
it.
A method is not required to declare in
its throws clause any subclasses of
Error that might be thrown during the
execution of the method but not
caught, since these errors are
abnormal conditions that should never
occur.
Cited from Java's own documentation of the class Error.
In short, you should not catch Errors, except you have a good reason to do so. (For example to prevent your implementation of web server to crash if a servlet runs out of memory or something like that.)
An Exception, on the other hand, is just a normal exception as in any other modern language. You will find a detailed description in the Java API documentation or any online or offline resource.
There is several similarities and differences between classes java.lang.Exception and java.lang.Error.
Similarities:
First - both classes extends java.lang.Throwable and as a result
inherits many of the methods which are common to be used when dealing
with errors such as: getMessage, getStackTrace, printStackTrace and
so on.
Second, as being subclasses of java.lang.Throwable they both inherit
following properties:
Throwable itself and any of its subclasses (including java.lang.Error) can be declared in method exceptions list using throws keyword. Such declaration required only for java.lang.Exception and subclasses, for java.lang.Throwable, java.lang.Error and java.lang.RuntimeException and their subclasses it is optional.
Only java.lang.Throwable and subclasses allowed to be used in the catch clause.
Only java.lang.Throwable and subclasses can be used with keyword - throw.
The conclusion from this property is following both java.lang.Error and java.lang.Exception can be declared in the method header, can be in catch clause, can be used with keyword throw.
Differences:
First - conceptual difference: java.lang.Error designed to be
thrown by the JVM and indicate serious problems and intended to stop
program execution instead of being caught(but it is possible as for
any other java.lang.Throwable successor).
A passage from javadoc description about java.lang.Error:
...indicates serious problems that a reasonable application should
not try to catch.
In opposite java.lang.Exception designed to represent errors that
expected and can be handled by a programmer without terminating
program execution.
A passage from javadoc description about java.lang.Exception:
...indicates conditions that a reasonable application might want to
catch.
The second difference between java.lang.Error and java.lang.Exception that first considered to be a unchecked exception for compile-time exception checking. As the result code throwing java.lang.Error or its subclasses don't require to declare this error in the method header. While throwing java.lang.Exception required declaration in the method header.
Throwable and its successor class diagram (properties and methods are omitted).
IMO an error is something that can cause your application to fail and should not be handled. An exception is something that can cause unpredictable results, but can be recovered from.
Example:
If a program has run out of memory it is an error as the application cannot continue. However, if a program accepts an incorrect input type it is an exception as the program can handle it and redirect to receive the correct input type.
Errors are mainly caused by the environment in which application is running. For example, OutOfMemoryError occurs when JVM runs out of memory or StackOverflowError occurs when stack overflows.
Exceptions are mainly caused by the application itself. For example, NullPointerException occurs when an application tries to access null object or ClassCastException occurs when an application tries to cast incompatible class types.
Source : Difference Between Error Vs Exception In Java
Here's a pretty good summary from Java API what an Error and Exception represents:
An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. The ThreadDeath error, though a "normal" condition, is also a subclass of Error because most applications should not try to catch it.
A method is not required to declare in
its throws clause any subclasses of
Error that might be thrown during the
execution of the method but not
caught, since these errors are
abnormal conditions that should never
occur.
OTOH, for Exceptions, Java API says:
The class Exception and its subclasses are a form of Throwable that indicates conditions that a reasonable application might want to catch.
Errors are caused by the environment where your application or program runs. Most times, you may not recover from it as this ends your application or program. Javadoc advised that you shouldn't bother catching such errors since the environment e.g. JVM, on such errors is going to quit anyway.
Examples:
VirtualMachineError - Thrown to indicate that the Java Virtual Machine is broken or has run out of resources necessary for it to continue operating.
OutOfMemoryError occurs when JVM runs out of memory or
StackOverflowError occurs when stack runs over.
Exceptions are caused by your application or program itself; maybe due to your own mistake. Most times you can recover from it and your application would still continue to run. You are advised to catch such errors to prevent abnormal termination of your application or program and/or to be able to customize the exception message so the users see a nicely formatted message instead of the default ugly exception messages scattered all over the place.
Examples:
NullPointerException occurs when an application tries to access null object. or
Trying to access an array with a non-existing index or calling a function with wrong data or parameters.