What type of exception is caught by the beanshell catch(ex): Exception or Throwable?.
Example:
try {
.... } catch (ex) { }
That loosely typed catch will catch everything "Throwable." That will include Errors, Exceptions and their myriad children. You can easily confirm this with:
try {
new Throwable("Something Exceptional");
} catch (ex) {
System.err.println(ex.getMessage());
}
Throwable is a superclass (essentially) of Exception--anything that Exception catches will also be caught by Throwable. In general usage they are the same, you rarely (if ever) see other throwable types.
Related
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.
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
I am trying to extend some legacy code to make it more tolerant of network outages. I have some (legacy) groovy code which wraps up a call to a webservice (CallWebService) via wslite. Sometimes, this call throws either a wslite.http.HTTPClientException or a java.net.ConnectException exception (this has been determined by adding
log.info("Exception " + ex.getClass().getName() + " throw");
to my log4j logging)
The code which calls this groovy code is in java and looks like the following:
public static String getDataFromWebService(String webServiceUrl, String referenceNumber) {
try {
ReturnedData returnedData = new CallWebService(webServiceUrl, referenceNumber);
return (String)returnedData.toXml();
}
catch (Exception ex) {
log.info("Exception caught: class of exception is " + ex.getClass().getName());
throw ex;
}
What I want to do, is catch the thrown exception (wslite.http.HTTPClientException or java.net.ConnectException) and retry the call (as it's probably a glitch) once or twice.
When I try and add
catch (java.net.ConnectException ex)
and build, the build fails with
exception ConnectException is never thrown in body of corresponding try statement
What should I do to be able to catch and react to the appropriate exceptions?
In your Java code, I would do something like this:
try {
callGroovy();
} catch (RuntimeException e) { // EDIT --- Should be Exception, RuntimeException
if (e instanceof HTTPClientException || e.getCause() instanceof ConnectException) {
throw e;
}
// log other exception...
}
This would be a bit safer than catching single exception types. In my experience, dynamic languages like groovy are more likely to throw unanticipated runtime exceptions. And catching all runtime exceptions would ensure that groovy exceptions do not infect the rest of your program.
I have the following piece of code
try{//do something
}
catch (Exception e) {
log.error(e, e);
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
} else {
throw new RuntimeException(e);
}
}
the findbugs stataic analysis tool throws this warning on it
instanceof will always return true for all nonnull values in methodX, since all RuntimeException are instances of RuntimeException
what i dont understand is that its Exception which is being caught and not the RuntimeException, so why this warning ?
Perhaps, the // do something code does not throw any checked exception, so the only exceptions you can get in your try-block are unchecked ones (subclassing RuntimeException).
You could also try following code. This will be better to read and maintain.
try{//do something
}
catch (RuntimeException e) {
throw e;
}
catch (Exception e) {
throw new RuntimeException(e);
}
Probably there is no methods that throws not RuntimeException in "try" part. Therefore, you can use construction
catch(RuntimeException e)
{
//Do something
}
Try http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Throwables.html#propagate%28java.lang.Throwable%29. It does exactly what you want. Today I did the replacement for the same reason (findbugs warning), also looked the source of this method.
In trying to refactor some I code I attempted to throw the exception in the catch clause like so -
try {
....
}
catch(Exception exception){
.....
throw exception
}
However when I attempted to throw the exception on line "throw exception" the compiler complained with a message that I needed to surround my throw clause in a new try/catch like so -
try
{
....
}
catch (Exception exception)
{
.....
try
{
throw exception
}
catch (Exception e2)
{
...
}
}
Why does the compiler require this and what use does it provide ?
Thanks
The exception java.lang.Exception is a checked exception. This means that it must either be declared in the throws clause of the enclosing method or caught and handled withing the method body.
However, what you are doing in your "fixed" version is to catch the exception, rethrow it and then immediately catch it again. That doesn't make much sense.
Without seeing the real code, it is not clear what the real solution should be, but I expect that the problem is in the original try { ... } catch handler:
If possible, you should catch a more specific exception at that point, so that when you rethrow it, it is covered by the method's existing throws list.
Alternatively, you could wrap the exception in an unchecked exception and throw that instead.
As a last resort, you could change the signature of the method to include Exception in the throws list. But that's a really bad idea, because it just pushes the problem off to the caller ... and leaves the developer / reader in the position of not knowing what exceptions to expect.
In Java, there is a distinction between checked and unchecked exceptions. An unchecked exception can essentially be thrown at any place in code and, if it's not caught somewhere, it will propagate up to the entry point of your application and then stop the process (usually with an error message and stack trace). A checked exception is different: The compiler won't let you just let it propagate, you need to either surround any code which might throw a checked exception with try-catch blocks (and "throw exception" is the simplest case if exception is an instance of a checked exception class) or you must mark the method which contains the call to code that might throw a checked exception with a "throws" declaration. If the desired behaviour is to throw an unchecked exception, then you'll need to wrap the exception in a RuntimeException. If the desired behaviour is to keep the exception checked, then you'll need to add a throws declaration to your current method.
In your original code, nothing catches the thrown exception. I would imagine you either have to specify that your function throws an exception or have another try/catch block as the compiler suggests to catch it.
Instead of
public void yourFunction(){
try {
....
}
catch(Exception exception){
.....
throw exception
}
}
try
public void yourFunction() throws Exception{
try {
....
}
catch(Exception exception){
.....
throw exception
}
}
My guess is that your trying to throw an exception sub class that isn't declared by the method as an exception type it can throw.
The following example works
package test.example;
public class ExceptionTest {
public static void main(String[] args) throws Exception{
try {
int value = 1/0;
} catch (Exception e) {
System.out.println("woops the world is going to end");
throw e;
}
}
}
However this example will give an error.
package test.example;
public class ExceptionTest {
public static void main(String[] args) throws RuntimeException{
try {
int value = 1/0;
} catch (Exception e) {
System.out.println("woops the world is going to end");
throw e;
}
}
}
Note in the second example I'm simply catching Exception not RuntimeException, it won't compile as I throw Exception which is an undeclared throws, even though I do declare RuntimeException.
Yes the exception is a RuntimeException but the compiler doesn't know that.
Just thought of a third working example to show you. This one also works because your throwing the same type as you declare. (note the only change is the catch block)
package test.example;
public class ExceptionTest {
public static void main(String[] args) throws RuntimeException{
try {
int value = 1/0;
} catch (RuntimeException e) {
System.out.println("woops the world is going to end");
throw e;
}
}
}
You need to understand the differences between all three of these answers