Why must I use try catch when I use global exception handling? - java

I'm beginner in Java and Android. My problem is when I use setDefaultUncaughtExceptionHandler in my code, some functions still need a try/catch block surrounding it, but I want throw all my exceptions to UncaughtException thread.
public class MyAlarmReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
Thread.setDefaultUncaughtExceptionHandler(new UnCaughtException(context));
try
{
String imageURL = MyWebService.readFeed();
DownloadAndSet.downloadFile(imageURL);
}
catch(Throwable e)
{
throw new RuntimeException(e);
}
Toast.makeText(context, "Alarm Triggered", Toast.LENGTH_LONG).show();
}
}

Java distinguishes checked and unchecked exceptions. Checked Exceptions have to be caught, no matter what.
Correction: Or you have to add the throws clause to the method. This postpones the urge to catch that exception to the caller of your method.
If you want them to be handled in the UncaughtExceptionHandler, you can "forward" them:
try{
// blah "throws some checked exception type"
} catch ( Throwable e ) {
// throw e; <- This will not work :( unless you add the "throws" clause.
throw new RuntimeException(e);
}
Unfortunately, just throwing the same Exception won't work, because you'd have to add the throws clause, which you do not want. You'll have to wrap it in a RuntimeException.

All checked exceptions in your code must be caught.
Further reading on checked vs unchecked exceptions:
http://www.javapractices.com/topic/TopicAction.do?Id=129
http://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html

When you call a method that throws an exception, requires you to either handle the exception using try/catch or throw the same exception.
As you don't want to handle the exception in your code and want all exceptions to be handled by your Default Exception handler so you need to add throws to all your methods where you don't want to catch the exception.

The documentation says:
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.
It doesn't relate to exceptions you have to catch. An example of an exception you have to catch/throw is IOException. An example of an exception you don't is NullPointerException.
So if your code causes a NullPointerException, the default handler will deal with it. If your code (potentially) causes an IOException, you have to deal with it then and there (either by catching or throwing).

What I have always done in my programs is create a exception handler method and call it every time I make a try/catch block. Many times I have had Thread.sleep() methods and I just send the exception to a common place to do "global" handling. In your global exception handler, you can also refer to this method.
Keep in mind that you might not always want to use this method because things like file streams might throw errors if a file already exists and you would want to take a different approach such as naming it something else than just stopping the program.
public static void main(String[] args) {
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
catchException(e);
}
});
try {
Thread.sleep(1000);// Just an example of a possible exception thrower
}
catch (InterruptedException e) {
catchException(e);
}
}
public static void catchException(Throwable e) {
// Deal with the exception here
System.out.println("Oh no! You broke the program!!!");
System.out.println("Here is the error btw: " + e.getMessage());
}
If you are using Eclipse, you can set the default automatic code generation for try/catch blocks to automatically include this method:
You can also set project specific settings if you don't want this behaviour for all of your projects.

Related

When and where to use throws instead of a try catch in Java? [duplicate]

Are these code statements equivalent?
Is there any difference between them?
private void calculateArea() throws Exception {
....do something
}
private void calculateArea() {
try {
....do something
} catch (Exception e) {
showException(e);
}
}
Yes, there's a huge difference - the latter swallows the exception (showing it, admittedly), whereas the first one will let it propagate. (I'm assuming that showException doesn't rethrow it.)
So if you call the first method and "do something" fails, then the caller will have to handle the exception. If you call the second method and "do something" fails, then the caller won't see an exception at all... which is generally a bad thing, unless showException has genuinely handled the exception, fixed whatever was wrong, and generally made sure that calculateArea has achieved its purpose.
You'll be able to tell this, because you can't call the first method without either catching Exception yourself or declaring that your method might throw it too.
They differ in where the responsibility to deal with the Exception lies. First one just throws Exception, so it does not handle it. The code that calls the method needs to handle the Exception. Second one catches and handles the Exception within the method, so in this case the caller doesn't have to do any exception handling, provided showException() itself does not throw another exception.
Yes. The version which declares throws Exception will require the calling code to handle the exception, while the version which explicitly handles it will not.
i.e., simply:
performCalculation();
vs. moving the burden of handling the exception to the caller:
try {
performCalculation();
catch (Exception e) {
// handle exception
}
Yes, there is a great deal of difference between them. The in the first code block, you pass the exception to the calling code. In the second code block you handle it yourself. Which method is correct depends entirely on what you are doing. In some instances, you want your code to handle the exception (if a file isn't found and you want to create it, for instance) but in others, you want the calling code to handle the exception (a file isn't found and they need to specify a new one or create it).
Generally speaking as well, you don't want to catch a generic exception. Instead, you'll want to catch only specific ones, such as FileNotFoundException or IOException because they can mean different things.
There is one particular scenario where we cannot use throws, we have got to use try-catch.
There is a rule "An overridden method cannot throw any extra exception other than what its parent class is throwing". If there is any extra exception that should be handled using try-catch.
Consider this code snippet.
There is a simple base class
package trycatchvsthrows;
public class Base {
public void show()
{
System.out.println("hello from base");
}
}
and it's derived class:
package trycatchvsthrows;
public class Derived extends Base {
#Override
public void show() {
// TODO Auto-generated method stub
super.show();
Thread thread= new Thread();
thread.start();
try {
thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// thread.sleep(10);
// here we can not use public void show() throws InterruptedException
// not allowed
}
}
When we have to call thread.sleep() we are forced to use try-catch, here we can not use:
public void show() throws InterruptedException
because overridden method can not throw extra exceptions.
If you threw an exception, the child method (which overrides this) should handle the exception
example:
class A{
public void myMethod() throws Exception{
//do something
}
}
A a=new A();
try{
a.myMethod();
}catch Exception(e){
//handle the exception
}
I assume that by "identical" you are referring to behavior.
A behavior of a function can be determined by:
1) Returned value
2) Thrown exceptions
3) Side effects (i.e changes in the heap, file system etc)
In this case, the first method propagates any exception, while the second throws no checked exception, and swallows most of the unchecked exceptions as well, so the behavior IS different.
However, if you guarantee that "do something" never throws an exception, then the behavior would be identical (though the compiler will require the caller to handle the exception, in the first version)
--edit--
From the point of view of API design, the methods are completely different in their contract. Also, throwing class Exception is not recommended. Try throwing something more specific to allow the caller to handle the exception better.
Many times you want the caller to handle the exception. Let's say you have the caller call a method which calls another method which calls another method, instead of having each method handle the exception, you can just handle it at the caller. Unless, you want to do something in one of the methods when that method fails.
The caller of this method will need to either catch this exception or declare it to be rethrown in it's method signature.
private void calculateArea() throws Exception {
// Do something
}
In the try-catch block example below. The caller of this method doesn't have to worry about handling the exception as it has already been taken care of.
private void calculateArea() {
try {
// Do something
} catch (Exception e) {
showException(e);
}
}
private void calculateArea() throws Exception {
....do something
}
This throws the exception,so the caller is responsible for handling that exception but if caller does not handle the exception then may be it will given to jvm which may result in abnormal termination of programe.
Whereas in second case:
private void calculateArea() {
try {
....do something
} catch (Exception e) {
showException(e);
}
}
Here the exception is handled by the callee,so there is no chance of abnormal termination of the program.
Try-catch is the recommended approach.
IMO,
Throws keyword mostly used with Checked exceptions to convince
compiler but it does not guarantees normal termination of program.
Throws keyword delegate the responsibility of exception handling to
the caller(JVM or another method).
Throws keyword is required for checked exceptions only ,for unchecked
exceptions there is no use of throws keyword.

Sonarqube - avoiding catch generic Exception

Sonar complains when catching the generic type Exception, but sometimes we need to do some general exception handling for ALL (even not yet recognized) exception types. What is the solution to pass this sonar check?
Unless you are invoking a method which throws Exception, there is no need to catch Exception: catch the exceptions you know about, and the compiler will tell you when you have to start handling another one.
The problem with catching "not yet recognized" Exceptions is that you lose the signal that you have to handle a new exception in a special way.
For example:
void someMethod() {
// Do stuff.
}
void callIt() {
try {
someMethod();
} catch (Exception e) {
// ...
}
}
If someMethod is now changed so that it throws, say, an InterruptedException:
void someMethod() throws InterruptedException {
Thread.sleep(1000);
// Do stuff.
}
you aren't told by the compiler that you need to add handling for the InterruptedException in callIt(), so you will silently swallow interruptions, which may be a source of problems.
If, instead, you had caught RuntimeException, or RuntimeException | IOException | OtherExceptionYouAlreadyKnowAbout, the compiler would flag that you had to change your code to handle that InterruptedException as well; or, that you can't change the signature of someMethod(), and the checked exception has to be handled there.

Handle exception in the called method/function Java/Android?

I got this method:
public void foo(){
int test = 5/0;
}
And I call it like this:
try {
foo();
} catch (Exception e){
e.printStackTrace();
}
This catches the ArithmeticException, but I have seen cases where I call a method inside try-catch, but it doesn't catch the exception. Is there a specific situation in which the exception may not be caught?
Here is an example to clarify the question:
Does the try-catch block in ActivityA catches the exception in ActivityB? I know the answer is negative. But I want to know the logic behind this.
public class ActivityA extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_a);
startActivity(new Intent(this, ActivityB.class));
} catch (Exception e){
e.printStackTrace();
}
}
}
And ActivityB:
public class ActivityB extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_b);
int x = 5/0
}
}
To all cool guys who think this is a duplicate question, please give me a link to a question on StackOverFlow that answers to this very clear question: Does a try-catch catches exceptions that happens in a method which is called inside it?
What may have happened is that you tried to catch in an exception that was not the one that was fired.
In the case of ArithmeticException, if you fire one, for example, NumberFormatException, it won't hold the Exception and will stop your application.
If you catch Exception, Exception itself and all exceptions that are a subtype of Exception will be caught by that block. In Java that will be the so called "checked exceptions".
However, you will not catch those "exceptions" that are only a subtype of Throwable. To be precise, those are not acctually exceptions. They are errors. It is also possible to catch them in a try-catch statement.
Not that neither catching Exception nor Throwable is a good practice. Always catch the specific exceptions and errors you are expecting.
If you specify an exception to be caught, e.g
public void foo(numb, divisor) throws ArithmeticException {
if (divisor == 0) throw new ArithmeticException();
int ans = num / divisor;
}
#Test
public void tesfooWithZeroDivisor() {
try {
foo(5, 0);
} catch (ArithmeticException e) {
System.out.println("Can't divide by zero");
}
}
In this case, you're specifying that you want an ArithmeticException to be caught if thrown. In the event that no ArithmeticException is thrown but a different exception such as IllegalArgumentException, then it will not catch an IllegalArgumentException because you only specify ArithmeticException.
In your case, you used catch (Exception e) which means you didn't specify an exception so it will catch any exception that got thrown regardless.
Is there a specific situation in which the exception may not be caught?
Some situations spring to mind:
The code (e.g. the call to foo()) was not executed. So the exception was not thrown.
The exception was thrown by different code; e.g. in your example, the foo() method is called from somewhere else; e.g. on a different thread stack.
The exception was caught further up the call chain.
You have declared your own exception (e.g. my.pkg.ArithmeticException) and you are catching a different exception to the one thrown as a result
If you do funky things with classloaders, it is possible to load the same class more than once. If you do that, you will have types that have the same name, but are in fact different. If you did that with an exception class, the instanceof test that the handler performs may fail to match.
Does a try-catch catches exceptions that happens in a method which is called inside it?
Yes. If you have implemented it properly; see above.
If you want chapter and verse, read JLS 14.20.
Concerning your updated example, I would not expect the exception handler for ActivityA to see exceptions thrown in ActivityB.onCreate. I would expect onCreate() to be called by a different thread.
You can confirm this by catching the exception in ActivityB.onCreate and looking at the stacktrace.

Intercept and rethrow a Java unhandled exception

I've coded a method with a catch-all handler, but I need to rethrow the exception as if it were unhandled, so that a caller (much) further up the call stack can handle it. The trivial way to do this is simply:
try {
...
} catch (Exception ex) {
// do something here...
// and rethrow
throw ex;
}
But the problem is that, because of the throw statement, Java requires this method to declare itself as throws Exception, which in turn, requires all the callers to handle the exception or declare themselves as throws Exception. And so on up the call chain...
Is there any simple way to rethrow the exception as if the current method did not handle it?
You have exactly two options with (checked) exceptions:
Handle them in the method via a try/catch (which may include rethrowing as a different exception type)
Declare that the method throws the exception.
If you want to rethrow the exception as if this method did not catch it, your only option is 2.
Note: you only want to catch (Exception e) if a method in the try block actually throws Exception. Otherwise, catch the specific exception types.
You could do what #radoh has said and just wrap into a RuntimeException, but one downside of this is your stacktrace is now polluted and will show the offending line to be where you declare throw new RuntimeException(ex).
An alternative is to use Lomboks SneakyThrows mechanism, like this:
public static void main(String[] args) {
methodWithException();
}
private static void methodWithException() {
try {
throw new Exception("Hello");
} catch (Exception e) {
Lombok.sneakyThrow(e);
}
}
Your stacktrace will remain intact, but you no longer need to declare throws Exception.
It's worth reading the documentation on why you should/shouldn't do this

Sample code to handle Exceptions

I am new to Android mobile application development.
I would like to know, how can I handle exceptions like HttpConnection related exceptions or any other exceptions? Do I need to display an AlertDialog to the user?
Kindly provide a sample code or project source code on how can I handle HttpConnection or similar type of Exceptions.
There are 2 different kinds of exceptions in Java: Checked and Unchecked. There is a big debate over which one is better to use, both arguments are good.
Basically a Checked exception is derived from java.lang.Exception and it requires that if you don't specify your method as "throws MyCheckedException" then you must catch and handle the exception within your method.
// throw the exception
void foo() throws MyCheckedException
{
throw new MyCheckedException();
}
// or handle the exception
void foo()
{
try {
throw new MyCheckedException();
} catch (MyRuntimeException e) {
e.printStackTrace();
}
}
An Unchecked exception, derived from java.lang.RuntimeException, requires neither that you specify "throws" in your method definition nor that you handle it.
void foo()
{
throw new MyUncheckedException();
}
The advantage of Checked is that the compiler will warn you when you haven't handled an exception.
The disadvantage is that you have to declare either a try/catch block or a throws for every Checked exception, and the upper level code can get pretty cumbersome, trying to handle all the different types of Exceptions.
For this reason, if you're careful you might prefer using Unchecked Exceptions.
BTW, you can only choose your exception type when you define your own.
When encountering Exceptions from Java or a 3rd party library, you have to decide how to handle it. e.g. If a 3rd party method throws CheckedException1, then you have to either handle it, or declare the calling method as "throws CheckedException1". If you want to avoid using Checked Exceptions then you can wrap it in an Unchecked Exception and throw that.
void foo() // no throws declaration
{
try {
thirdPartyObj.thirdPartyMethod(); // this throws CheckedException1
}
catch (CheckedException1 e) {
throw new MyUncheckedException(e); // this will wrap the checked in an unchecked.
}
}
Note that you can throw the Unchecked exception without the "throws" declaration. To access the original CheckedException1 from higher up, you can use the .getCause() method of your Unchecked exception.
void caller()
{
try {
foo();
} catch (MyUncheckedException e) {
CheckedException1 ce1 = e.getCause();
ce1.printStackTrace();
}
}
... but because the exception from foo() is Unchecked, you don't have to handle it or declare "throws".
Regarding logging, there are different schools of thought on this.
Log it when the exception occurs (low - level)
Log it when it reaches the top (high - level)
Log it when you have enough information to make an appropriate action and/or a log message. (mid - level)
A good policy I've found is to install an uncaught exception handler which will take care of all uncaught (obviously unchecked) exceptions. This way anything that is missed will be logged and potentially handled before crashing the system.
public class MyExceptionHandler implements UncaughtExceptionHandler
{
#Override
public void uncaughtException(Thread thread, Throwable ex)
{
ex.printStackTrace();
}
}
// In your high-level code
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler());
and all for Exceptions that can be handled gracefully, catch and handle them in a module where you know enough about the situation to possibly correct the problem and try again.
How you handle exception depends on the exception. If the exception is something that you cannot recover from, and the user needs to know about then you could catch the exception and show it in an AlertDialog:
try {
// do something
} catch (SomeImportantException e) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("User friendly text explaining what went wrong.");
AlertDialog alert = builder.create();
alert.show();
}
For more info on the dialog, see creating dialogs.
Alternatively, if the exception is something that you can deal with, you can just log information about the exception and move on.
try {
// do something
} catch (SomeLessImportantException e) {
Log.d(tag, "Failed to do something: " + e.getMessage());
}
You could use the ACRA plugin that offers this functionality or BugSense to gather error reports.
Disclaimer: I am a founder at BugSense.

Categories

Resources