So, I know this is going to sound a little extreme but I'm trying to make a point:
OK. so my code doesn't care what kind of exception is being thrown, 99.9% of the time if an exception is being thrown it handles it the same no matter what.
Now, Why should i even bother throwing \ creating new exception in my code?
apparently all the libraries i use throw them already and the are very informative as well.
a null object passed for my method? who cares, a null pointer exception will be thrown automatically for me.
Can you make a good argument why should i create new exceptions and throw them?
EDIT what i mean:
why bother with this:
public myMethod() {
try {
doStuff1();
}
catch(Exception e) {
throw new Exception("Error in doStuff1");
}
try {
doStuff2();
}
catch(Exception e) {
throw new Exception("Error in doStuff2");
}
when i can use this:
public myMethod() {
doStuff1();
doStuff2();
}
Your client wants detailed error reporting. What went wrong, and where did it go wrong.
They don't have a clue what a null pointer exception is. And even then, that in itself is not particularly helpful without the stack trace. So a null pointer gets passed into your RetrieveReportX method? Check if it's null and throw a ReportXNoIdentifierException rather than letting it auto-throw a null pointer exception. Then you'll have a error handler somewhere that, based on these custom exceptions, can report exactly what went wrong in what (human) process, and your client is happy because rather than NullPointerException at [stacktrace], they can see "An identifier was not supplied when attempting to retrieve report X."
why should i create new exceptions and throw them?
In some cases it is common and good practice to throw Exception deliberately.
Take
IllegalArgumentException
If your method only accepts arguments within a particular range, e.g. only positive numbers, then you should check for invalid parameters and throw an IllegalArgumentException.
For example:
public int calculateFactorial(int n) {
if (n < 0)
throw new IllegalArgumentException("n must be positive");
if (n >= 60)
throw new IllegalArgumentException("n must be < 60");
...
}
public void findFactorial(int n)
{
try{
calculateFactorial(n)
}catch(IllegalArgumentException ie){
System.out.println(ie.getMessage());
}
}
From Java tutorials - Advantages of Exceptions
Advantage 1: Separating Error-Handling Code from "Regular" Code
Advantage 2: Propagating Errors Up the Call Stack
Advantage 3: Grouping and Differentiating Error Types
Answer
Exception handlers that are too general can make code more error-prone by catching and handling exceptions that weren't anticipated by the programmer and for which the handler was not intended.
As noted, you can create groups of exceptions and handle exceptions in a general fashion, or you can use the specific exception type to differentiate exceptions and handle exceptions in an exact fashion.
Related
In Java, is there an elegant way to detect if an exception occurred prior to running the finally block? When dealing with "close()" statements, it's common to need exception handling within the finally block. Ideally, we'd want to maintain both exceptions and propagate them up (as both of them may contain useful information). The only way I can think of to do this is to have a variable outside the try-catch-finally scope to save a reference to a thrown exception. Then propagate the "saved" exception up with any that occur in the finally block.
Is there a more elegant way of doing this? Perhaps an API call that will reveal this?
Here's some rough code of what I'm talking about:
Throwable t = null;
try {
stream.write(buffer);
} catch(IOException e) {
t = e; //Need to save this exception for finally
throw e;
} finally {
try {
stream.close(); //may throw exception
} catch(IOException e) {
//Is there something better than saving the exception from the exception block?
if(t!=null) {
//propagate the read exception as the "cause"--not great, but you see what I mean.
throw new IOException("Could not close in finally block: " + e.getMessage(),t);
} else {
throw e; //just pass it up
}
}//end close
}
Obviously, there are a number of other similar kludges that might involve saving the exception as an member variable, returning it from a method, etc... but I'm looking for something a bit more elegant.
Maybe something like Thread.getPendingException() or something similar? For that matter, is there an elegant solution in other languages?
This question actually spawned from comments in another question that raised an interesting question.
Your idea about setting a variable outside the scope of the try/catch/finally is correct.
There cannot be more than one exception propagating at once.
Instead of using a Boolean flag, I would store a reference to the Exception object.
That way, you not only have a way to check whether an exception occurred (the object will be null if no exception occurred), but you'll also have access to the exception object itself in your finally block if an exception did occur. You just have to remember to set the error object in all your catch blocks (iff rethrowing the error).
I think this is a missing C# language feature that should be added. The finally block should support a reference to the base Exception class similar to how the catch block supports it, so that a reference to the propagating exception is available to the finally block. This would be an easy task for the compiler, saving us the work of manually creating a local Exception variable and remembering to manually set its value before re-throwing an error, as well as preventing us from making the mistake of setting the Exception variable when not re-throwing an error (remember, it's only the uncaught exceptions we want to make visible to the finally block).
finally (Exception main_exception)
{
try
{
//cleanup that may throw an error (absolutely unpredictably)
}
catch (Exception err)
{
//Instead of throwing another error,
//just add data to main exception mentioning that an error occurred in the finally block!
main_exception.Data.Add( "finally_error", err );
//main exception propagates from finally block normally, with additional data
}
}
As demonstrated above... the reason that I'd like the exception available in the finally block, is that if my finally block did catch an exception of its own, then instead of overwriting the main exception by throwing a new error (bad) or just ignoring the error (also bad), it could add the error as additional data to the original error.
You could always set a boolean flag in your catch(es). I don't know of any "slick" way to do it, but then I'm more of a .Net guy.
Use logging...
try {
stream.write(buffer);
} catch(IOException ex) {
if (LOG.isErrorEnabled()) { // You can use log level whatever you want
LOG.error("Something wrong: " + ex.getMessage(), ex);
}
throw ex;
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException ex) {
if (LOG.isWarnEnabled()) {
LOG.warn("Could not close in finally block", ex);
}
}
}
}
In vb.net, it's possible to use a "Catch...When" statement to grab an exception to a local variable without having to actually catch it. This has a number of advantages. Among them:
If nothing is going to 'ultimately' catch the exception, an unhandled exception trap will be fired from the spot of the original exception. Much nicer than having the debugger trap at the last rethrow, especially since information that might be needed for debugging won't yet have gone out of scope or been swept up by 'finally' statements.
Although a rethrow won't clear the stack trace the way "Throw Ex" would, it will still often jinx the stack trace. If the exception isn't caught, the stack trace will be clean.
Because this feature is unsupported in vb, it may be helpful to write a vb wrapper to implement the code in C (e.g. given a MethodInvoker and an Action(Of Exception), perform the MethodInvoker within a "Try" and the Action in a "Finally".
One interesting quirk: it's possible for the Catch-When to see an exception which will end up getting overwritten by a Finally-clause exception. In some cases, this may be a good thing; in other cases it may be confusing. In any event, it's something to be aware of.
I'd like to know what is the best way or best-practice to handle this kind of situation. Guess a straightforward function like this:
public Object f1() {
Object result = null;
try {
String payload = methodThrowsAnException();
result = payload;
} catch (IOException e) {
throw new IllegalStateException(e); <<<<<<<<<<<<<<<
}
return result;
}
I'd like to know if it's a good practice:
to re-throw the exception or
return a null when something has been wrong inside.
I don't know if I've explained so well.
Re-throwing caught exception is a bad idea. most often, the stacktrace will contain more or less detailed information about your architecture. This would be to useful for an attacker.
I wouldn't allow my app to get into illegal state because of the user's action. In your case, I would say:
try {
String payload = methodThrowsAnException();
result = payload;
} catch (IOException e) {
throw new IllegalArgumentException(<user's input which caused the exception>); <<<<<<<<<<<<<<<
}
There is nothing wrong with returning a null from your method if there is a particular scenario where you expect that exception.
Alternatively you can just allow the Exception to bubble up, and be handled by the caller.
When would I catch and re-throw an exception? When I can convey better meaning by throwing a new exception.
Would I include the original exception when I throw a new one? I would do it if it is a unknown/unexpected scenario which requires further debugging.
Let me share some examples:
Something unrecoverable like Out of DB Connection. I would just let the exception bubble up. It should get handled just before it reaches the user, and probably end up in a generic error message like 'Service not available. Please try again later'.
Something application related... such as backup file not found. In that case I will swallow up the FileNotFoundException and instead I will throw a BackupFileMissingException which is specific to my application. Here I don't need to include the FileNotFoundException because it is an expected scenario and there is nothing further to investigate.
I call some other API and they throw an exception, which is not documented. In this case, I will translate it into my application exception such as InterfaceApiException and include the original exception, so that it can be logged at the REST/Action layer along with the root cause.
Is there a better way for catching specific Exception with a message then doing this:
try{
methodThatWillProbablyThrowASocketException();
} catch(SocketException e){
if(e.getMessage().contains("reset")){
// the connection was reset
// will ignore
} else{
throw e;
}
}
For example the HttpStatusException gives me the Method getStatusCode() where i can easily compare if the error status was 404 or 502 and the can decide what to do:
try{
methodThatWillProbablyThrowAHTTPException();
} catch(HttpStatusException e){
if(e.getStatusCode() == 404){
// not found, will not continue
}
if else(e.getStatusCode() == 502){
// server errror, try again
} else{
throw e;
}
}
Most other Exceptions dont give me prober Methods, just the Message.
So my question is, is it the right way to do it? With String compares? Or is there a better way?
Just do one thing .
Collect all types of exception that are likely to be occur for your project.
Make a separate class by extending Exception.
Override the getCause() method.
http://docs.oracle.com/javase/6/docs/api/java/lang/Throwable.html#getCause%28%29
public Throwable getCause()
Define codes you want for different exceptions Like null-pointer 101 ,, so on......
The use that class every where . So you have to write exception only once and you can use with as many projects.
After building the class it will be reusable for all your needs
If you getting new conditions, update this class only and all the things will be done
This is a better solution according to me...
This way you can get functionality for which you are looking. you have to make it by yourself.
Relying on code or status code is fine but relying on message could be problematic as the message can change.
You should look to refactor and define multiple exceptions or define codes for different scenarios.
I was trying to understand why to use exceptions.
Suppose if I have an program,
(without using try/catch)
public class ExceptionExample {
private static String str;
public static void main(String[] args) {
System.out.println(str.length());
}
I got exception
Exception in thread "main" java.lang.NullPointerException
at com.Hello.ExceptionExample.ExceptionExample.main(ExceptionExample.java:22)
Now using try/catch,
public class ExceptionExample {
private static String str;
public static void main(String[] args) {
try {
System.out.println(str.length());
} catch(NullPointerException npe) {
npe.printStackTrace();
}
}
}
I got Exception,
java.lang.NullPointerException
at com.Hello.ExceptionExample.ExceptionExample.main(ExceptionExample.java:9)
Now my question is,
In both the cases I have got the same message printed. So what is the use of using try/catch? and
What can we do after catching exception, in this case I have printed the stack trace. Is catch used only for printing the trace or for finding exception details using getMessage() or getClass()?
The difference is pretty big, actually.
Take the first one and add a line after the print:
public class ExceptionExample {
private static String str;
public static void main(String[] args) {
System.out.println(str.length());
System.out.println("Does this execute?");
}
}
You'll see that Does this execute? isn't printed because the exception interrupts the flow of the code and stops it when it isn't caught.
On the other hand:
public class ExceptionExample {
private static String str;
public static void main(String[] args) {
try {
System.out.println(str.length());
} catch(NullPointerException npe) {
npe.printStackTrace();
}
System.out.println("Does this execute?");
}
}
Will print both the stack trace and Does this execute?. That's because catching the exception is like saying, "We'll handle this here and continue executing."
One other remark, the catch block is where error recovery should happen, so if an error occurs but we can recover from it, we put the recovery code there.
Edit:
Here's an example of some error recovery. Let's say we have a non-existent file at C:\nonexistentfile.txt. We want to try and open it, and if we can't find it, show the user a message saying it's missing. This could be done by catching the FileNotFoundException produced here:
// Here, we declare "throws IOException" to say someone else needs to handle it
// In this particular case, IOException will only be thrown if an error occurs while reading the file
public static void printFileToConsole() throws IOException {
File nonExistent = new File("C:/nonexistentfile.txt");
Scanner scanner = null;
try {
Scanner scanner = new Scanner(nonExistent);
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
} catch (FileNotFoundException ex) {
// The file wasn't found, show the user a message
// Note use of "err" instead of "out", this is the error output
System.err.println("File not found: " + nonExistent);
// Here, we could recover by creating the file, for example
} finally {
if (scanner != null) {
scanner.close();
}
}
}
So there's a few things to note here:
We catch the FileNotFoundException and use a custom error message instead of printing the stack trace. Our error message is cleaner and more user-friendly than printing a stack trace. In GUI applications, the console may not even be visible to the user, so this may be code to show an error dialog to the user instead. Just because the file didn't exist doesn't mean we have to stop executing our code.
We declare throws IOException in the method signature instead of catching it alongside the FileNotFoundException. In this particular case, the IOException will be thrown here if we fail to read the file even though it exists. For this method, we're saying that handling errors we encounter while reading the file isn't our responsibility. This is an example of how you can declare an irrecoverable error (by irrecoverable, I mean irrecoverable here, it may be recoverable somewhere further up, such as in the method that called printFileToConsole).
I accidentally introduced the finally block here, so I'll explain what it does. It guarantees that if the Scanner was opened and an error occurs while we're reading the file, the Scanner will be closed. This is important for many reasons, most notably that if you don't close it, Java will still have the lock on the file, and so you can't open the file again without exiting the application.
There are two cases when you should throw an exception:
When you detect an error caused by incorrect use of your class (i.e. a programming error) throw an instance of unchecked exception, i.e. a subclass of RuntimeException
When you detect an error that is caused by something other than a programming error (invalid data, missing network connectivity, and so on) throw an instance of Exception that does not subclass RuntimeException
You should catch exceptions of the second kind, and not of the first kind. Moreover, you should catch exceptions if your program has a course of action to correct the exceptional situation; for example, if you detect a loss of connectivity, your program could offer the user to re-connect to the network and retry the operation. In situations when your code cannot adequately deal with the exception, let it propagate to a layer that could deal with it.
try/catch will prevent your application from crashing or to be precise- the execution will not stop if an unintentional condition is met. You can wrap your "risky" code in try block and in catch block you can handle that exception. By handling, it means that do something about that condition and move on with execution.
Without try/catch the execution stopped at the error-making-line and any code after that will not be executed.
In your case, you could have printed "This was not what I expected, whatever, lets move on!"
Let's say you are connected to database but while reading the records, it throws some exception. Now in this particular case, you can close the connection in Finally block. You just avoided memory leak here.
What I meant to say is , you can perform your task even if exception is thrown by catching and handling it.
In the example you've given, you're right, there is no benefit.
You should only catch an exception if either
You can do something about it (report, add information, fix the situation), or
You have to, because a checked exception forces you to
Usual "handling" of an exception is logging the situation to a log file of your choosing, adding any relevant context-sesitive information, and letting the flow go on. Adding contextual information benefits greatly in resolving the issue. So, in your example, you could have done
public static void main(String[] args) {
try {
System.out.println(str.length());
} catch(NullPointerException npe) {
System.err.println(
"Tried looking up str.length from internal str variable,"
+" but we got an exception with message: "
+ npe.getMessage());
npe.printStackTrace(System.err);
}
}
when looking a message like that, someone will know based on the message what went wrong and maybe even what might be done to fix it.
If you are using Exception, don't
catch(NullPointerException npe) {
npe.printStackTrace();
}
simply
catch(NullPointerException npe) {
//error handling code
}
You are menat to remove error printing. And anyways catch general exception not just specific ones.
If you look at the two exceptions, they are actually different. The first one is referring to line 22, while the second one is referring to line 9. It sounds like adding the try/catch caught the first exception, but another line of code also threw an exception.
Consequently, the exception is being thrown because you never created a new String, or set a value to the string, unless it was done in a part of the code that is not shown.
Adding a try/catch block can be very helpful with objects that you have little to no control over, so if these objects are other than expected (such as null), you can handle the issue properly.
A string is normally something that you would instantiate first, so you shouldn't normally have to worry about using a try/catch.
Hope this helps.
To answer your original question Che, "when to use an exception?"
In Java - I'm sure you've already found out... There are certain methods in Java that REQUIRE the try / catch. These methods "throw" exceptions, and are meant to. There is no way around it.
For example,
FileUtils.readFileToString(new File("myfile.txt"));
won't let you compile until you add the try/catch.
On the other hand, exceptions are very useful because of what you can get from them.
Take Java Reflection for example...
try { Class.forName("MyClass").getConstructor().newInstance(); }
catch ( ClassNotFoundException x ) { // oh it doesnt exist.. do something else with it.
So to answer your question fully -
Use Try/Catch sparingly, as it's typically "frowned on" to EXPECT errors in your application.. on the contrary, use them when your methods require them.
Is it a bad practice to catch Throwable?
For example something like this:
try {
// Some code
} catch(Throwable e) {
// handle the exception
}
Is this a bad practice or we should be as specific as possible?
You need to be as specific as possible. Otherwise unforeseen bugs might creep away this way.
Besides, Throwable covers Error as well and that's usually no point of return. You don't want to catch/handle that, you want your program to die immediately so that you can fix it properly.
This is a bad idea. In fact, even catching Exception is usually a bad idea. Let's consider an example:
try {
inputNumber = NumberFormat.getInstance().formatNumber( getUserInput() );
} catch(Throwable e) {
inputNumber = 10; //Default, user did not enter valid number
}
Now, let's say that getUserInput() blocks for a while, and another thread stops your thread in the worst possible way ( it calls thread.stop() ). Your catch block will catch a ThreadDeath Error. This is super bad. The behavior of your code after catching that Exception is largely undefined.
A similar problem occurs with catching Exception. Maybe getUserInput() failed because of an InterruptException, or a permission denied exception while trying to log the results, or all sorts of other failures. You have no idea what went wrong, as because of that, you also have no idea how to fix the problem.
You have three better options:
1 -- Catch exactly the Exception(s) you know how to handle:
try {
inputNumber = NumberFormat.getInstance().formatNumber( getUserInput() );
} catch(ParseException e) {
inputNumber = 10; //Default, user did not enter valid number
}
2 -- Rethrow any exception you run into and don't know how to handle:
try {
doSomethingMysterious();
} catch(Exception e) {
log.error("Oh man, something bad and mysterious happened",e);
throw e;
}
3 -- Use a finally block so you don't have to remember to rethrow:
Resources r = null;
try {
r = allocateSomeResources();
doSomething(r);
} finally {
if(r!=null) cleanUpResources(r);
}
Also be aware that when you catch Throwable, you can also catch InterruptedException which requires a special treatment. See Dealing with InterruptedException for more details.
If you only want to catch unchecked exceptions, you might also consider this pattern
try {
...
} catch (RuntimeException exception) {
//do something
} catch (Error error) {
//do something
}
This way, when you modify your code and add a method call that can throw a checked exception, the compiler will remind you of that and then you can decide what to do for this case.
straight from the javadoc of the Error class (which recommends not to catch these):
* An <code>Error</code> is a subclass of <code>Throwable</code>
* that indicates serious problems that a reasonable application
* should not try to catch. Most such errors are abnormal conditions.
* The <code>ThreadDeath</code> error, though a "normal" condition,
* is also a subclass of <code>Error</code> because most applications
* should not try to catch it.
* A method is not required to declare in its <code>throws</code>
* clause any subclasses of <code>Error</code> that might be thrown
* during the execution of the method but not caught, since these
* errors are abnormal conditions that should never occur.
*
* #author Frank Yellin
* #version %I%, %G%
* #see java.lang.ThreadDeath
* #since JDK1.0
It's not a bad practice if you absolutely cannot have an exception bubble out of a method.
It's a bad practice if you really can't handle the exception. Better to add "throws" to the method signature than just catch and re-throw or, worse, wrap it in a RuntimeException and re-throw.
Catching Throwable is sometimes necessary if you are using libraries that throw Errors over-enthusiastically, otherwise your library may kill your application.
However, it would be best under these circumstances to specify only the specific errors thrown by the library, rather than all Throwables.
The question is a bit vague; are you asking "is it OK to catch Throwable", or "is it OK to catch a Throwable and not do anything"? Many people here answered the latter, but that's a side issue; 99% of the time you should not "consume" or discard the exception, whether you are catching Throwable or IOException or whatever.
If you propagate the exception, the answer (like the answer to so many questions) is "it depends". It depends on what you're doing with the exception—why you're catching it.
A good example of why you would want to catch Throwable is to provide some sort of cleanup if there is any error. For example in JDBC, if an error occurs during a transaction, you would want to roll back the transaction:
try {
…
} catch(final Throwable throwable) {
connection.rollback();
throw throwable;
}
Note that the exception is not discarded, but propagated.
But as a general policy, catching Throwable because you don't have a reason and are too lazy to see which specific exceptions are being thrown is poor form and a bad idea.
Throwable is the base class for all classes than can be thrown (not only exceptions). There is little you can do if you catch an OutOfMemoryError or KernelError (see When to catch java.lang.Error?)
catching Exceptions should be enough.
it depends on your logic or to be more specific to your options / possibilities. If there is any specific exception that you can possibly react on in a meaningful way, you could catch it first and do so.
If there isn't and you're sure you will do the same thing for all exceptions and errors (for example exit with an error-message), than it is not problem to catch the throwable.
Usually the first case holds and you wouldn't catch the throwable. But there still are plenty of cases where catching it works fine.
Although it is described as a very bad practice, you may sometimes find rare cases that it not only useful but also mandatory. Here are two examples.
In a web application where you must show a meaning full error page to user.
This code make sure this happens as it is a big try/catch around all your request handelers ( servlets, struts actions, or any controller ....)
try{
//run the code which handles user request.
}catch(Throwable ex){
LOG.error("Exception was thrown: {}", ex);
//redirect request to a error page.
}
}
As another example, consider you have a service class which serves fund transfer business. This method returns a TransferReceipt if transfer is done or NULL if it couldn't.
String FoundtransferService.doTransfer( fundtransferVO);
Now imaging you get a List of fund transfers from user and you must use above service to do them all.
for(FundTransferVO fundTransferVO : fundTransferVOList){
FoundtransferService.doTransfer( foundtransferVO);
}
But what will happen if any exception happens? You should not stop, as one transfer may have been success and one may not, you should keep go on through all user List, and show the result to each transfer. So you end up with this code.
for(FundTransferVO fundTransferVO : fundTransferVOList){
FoundtransferService.doTransfer( foundtransferVO);
}catch(Throwable ex){
LOG.error("The transfer for {} failed due the error {}", foundtransferVO, ex);
}
}
You can browse lots of open source projects to see that the throwable is really cached and handled. For example here is a search of tomcat,struts2 and primefaces:
https://github.com/apache/tomcat/search?utf8=%E2%9C%93&q=catch%28Throwable
https://github.com/apache/struts/search?utf8=%E2%9C%93&q=catch%28Throwable
https://github.com/primefaces/primefaces/search?utf8=%E2%9C%93&q=catch%28Throwable
Generally speaking you want to avoid catching Errors but I can think of (at least) two specific cases where it's appropriate to do so:
You want to shut down the application in response to errors, especially AssertionError which is otherwise harmless.
Are you implementing a thread-pooling mechanism similar to ExecutorService.submit() that requires you to forward exceptions back to the user so they can handle it.
Throwable is the superclass of all the errors and excetions.
If you use Throwable in a catch clause, it will not only catch all exceptions, it will also catch all errors. Errors are thrown by the JVM to indicate serious problems that are not intended to be handled by an application. Typical examples for that are the OutOfMemoryError or the StackOverflowError. Both are caused by situations that are outside of the control of the application and can’t be handled. So you shouldn't catch Throwables unless your are pretty confident that it will only be an exception reside inside Throwable.
If we use throwable, then it covers Error as well and that's it.
Example.
public class ExceptionTest {
/**
* #param args
*/
public static void m1() {
int i = 10;
int j = 0;
try {
int k = i / j;
System.out.println(k);
} catch (Throwable th) {
th.printStackTrace();
}
}
public static void main(String[] args) {
m1();
}
}
Output:
java.lang.ArithmeticException: / by zero
at com.infy.test.ExceptionTest.m1(ExceptionTest.java:12)
at com.infy.test.ExceptionTest.main(ExceptionTest.java:25)
A more differentiated answer would be: it depends.
The difference between an Exception and an Error is that an Exception is a state that has to be expected, while an Error is an unexpected state, which is usually fatal. Errors usually cannot be recovered from and require resetting major parts of the program or even the whole JVM.
Catching Exceptions is something you should always do to handle states that are likely to happen, which is why it is enforced by the JVM. I.E. opening a file can cause a FileNotFoundException, calling a web resource can result in a TimeoutException, and so on. Your code needs to be prepared to handle those situations as they can commonly occur. How you handle those is up to you, there is no need to recover from everything, but your application should not boot back to desktop just because a web-server took a little longer to answer.
Catching Errors is something you should do only if it is really necessary. Generally you cannot recover from Errors and should not try to, unless you have a good reason to. Reasons to catch Errors are to close critical resources that would otherwise be left open, or if you i.E. have a server that runs plugins, which can then stop or restart the plugin that caused the error. Other reasons are to log additional information that might help to debug that error later, in which case you of course should rethrow it to make sure the application terminates properly.
Rule of thumb: Unless you have an important reason to catch Errors, don't.
Therefore use catch (Throwable t) only in such really important situation, otherwise stick to catch (Exception e)