Scala doesn't have checked exceptions. However, when calling scala code from java, it's desirable to catch exceptions thrown by scala.
Scala:
def f()=
{
//do something that throws SomeException
}
Java:
try
{ f() }
catch (SomeException e)
{}
javac doesn't like this, and complains that "this exception is never thrown from the try statement body"
Is there a way to make scala declare that it throws a checked exception?
Use a throws annotation:
#throws(classOf[SomeException])
def f()= {
//do something that throws SomeException
}
You can also annotate a class constructor:
class MyClass #throws(classOf[SomeException]) (arg1: Int) {
}
This is covered in the Tour of Scala
You can still catch too many exceptions and then re-throw the ones you can't handle:
try { f(); }
catch (Exception e) {
if (e instanceof SomeException) // Logic
else throw e;
}
Related
I have the following scenario:
Class C{
mainCall(){
try{
//do something;
}catch(MyException e)
//doSomethingElse;
}
}
Class A{
methodOne() throws myException{
b.callMethodTwo();
}
}
class B{
callMethodTwo() throws myException{
try {
value = callService()//call some service
} catch(HttpClientErrorException | HttpServerErrorException e){
throw new MyException(e);
}
return value;
}
}
if some exceptions occured in callMethodTwo() (not HttpClientErrorException or HttpServerErrorException). What would be the flow in this case? Would the catch part in mainCall() in method C execute? I have almost 5 chain call in my code but tried to simplify here and generated this sceario.
if the statement value = callService(); in the method callMethodTwo throws
an exception of type HttpClientErrorException or HttpServerErrorException or their subtypes, it will be caught by the following catch block. This catch block will throw a new exception of type MyException which will be bubble up to methodOne which in turn bubble it up to mainCall where it will be finally caught by the catch block.
an exception of type MyException or its subtypes, it will be bubbled up from callMethodTwo to callMethodOne to mainCall where it will be finally caught by the catch block.
an exception of any other type, it will be bubbled up from callMethodTwo to callMethodOne to mainCall to the calling method of mainCall.
Exception other than handled exception wont be going into that catch block, so myException will not be thrown by callMethodTwo.
Execute and validate it. You'll never forget. callMethodTwo() will throw uncaught exception. A.methodOne() will throw the same back to. C.catch will catch it.
you have not called any method of A/B in C mainCall(). You should have some code which could throw MyException then only you can catch there.
I have some code that might throw both checked and runtime exceptions.
I'd like to catch the checked exception and wrap it with a runtime exception. But if a RuntimeException is thrown, I don't have to wrap it as it's already a runtime exception.
The solution I have has a bit overhead and isn't "neat":
try {
// some code that can throw both checked and runtime exception
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
Any idea for a more elegant way?
I use a "blind" rethrow to pass up checked exceptions. I have used this for passing through the Streams API where I can't use lambdas which throw checked exceptions. e.g We have ThrowingXxxxx functional interfaces so the checked exception can be passed through.
This allows me to catch the checked exception in a caller naturally without needing to know a callee had to pass it through an interface which didn't allow checked exceptions.
try {
// some code that can throw both checked and runtime exception
} catch (Exception e) {
throw rethrow(e);
}
In a calling method I can declare the checked exception again.
public void loadFile(String file) throws IOException {
// call method with rethrow
}
/**
* Cast a CheckedException as an unchecked one.
*
* #param throwable to cast
* #param <T> the type of the Throwable
* #return this method will never return a Throwable instance, it will just throw it.
* #throws T the throwable as an unchecked throwable
*/
#SuppressWarnings("unchecked")
public static <T extends Throwable> RuntimeException rethrow(Throwable throwable) throws T {
throw (T) throwable; // rely on vacuous cast
}
There is a lot of different options for handling exceptions. We use a few of them.
https://vanilla-java.github.io/2016/06/21/Reviewing-Exception-Handling.html
Guava's Throwables.propagate() does exactly this:
try {
// some code that can throw both checked and runtime exception
} catch (Exception e) {
throw Throwables.propagate(e);
}
UPDATE: This method is now deprecated. See this page for a detailed explanation.
Not really.
If you do this a lot, you could tuck it away into a helper method.
static RuntimeException unchecked(Throwable t){
if (t instanceof RuntimeException){
return (RuntimeException) t;
} else if (t instanceof Error) { // if you don't want to wrap those
throw (Error) t;
} else {
return new RuntimeException(t);
}
}
try{
// ..
}
catch (Exception e){
throw unchecked(e);
}
I have a specially compiled .class file containing the following:
public class Thrower {
public static void Throw(java.lang.Throwable t) {
throw t;
}
}
It just works. The java compiler would normally refuse to compile this, but the bytecode verifier doesn't care at all.
The class is used similar to Peter Lawrey's answer:
try {
// some code that can throw both checked and runtime exception
} catch (Exception e) {
Thrower.Throw(e);
}
You can rewrite the same using instanceof operator
try {
// some code that can throw both checked and runtime exception
} catch (Exception e) {
if (e instanceof RuntimeException) {
throw e;
} else {
throw new RuntimeException(e);
}
}
However, your solution looks better.
The problem is that Exception is too broad. You should know exactly what the possible checked exceptions are.
try {
// code that throws checked and unchecked exceptions
} catch (IOException | SomeOtherException ex) {
throw new RuntimeException(ex);
}
The reasons why this wouldn't work reveal deeper problems that should be addressed instead:
If a method declares that it throws Exception then it is being too broad. Knowing that "something can go wrong" with no further information is of no use to a caller. The method should be using specific exception classes in a meaningful hierarchy, or using unchecked exceptions if appropriate.
If a method throws too many different kinds of checked exception then it is too complicated. It should either be refactored into multiple simpler methods, or the exceptions should be arranged in a sensible inheritance hierarchy, depending on the situation.
Of course there can be exceptions to the rule. Declaring a method throws Exception can be perfectly reasonable if it's consumed by some kind of cross-cutting framework (such as JUnit or AspectJ or Spring) rather than comprising an API for others to use.
I generally use the same type of code structure, but condense it down to one line in one of the few times a ternary operator actually makes code better:
try {
// code that can throw
}
catch (Exception e) {
throw (e instanceof RuntimeException) ? (RuntimeException) e : new RuntimeException(e);
}
This does not require additional methods or catch blocks which is why I like it.
lombok has this handled with a simple annotation on the method 😊
Example:
import lombok.SneakyThrows;
#SneakyThrows
void methodThatUsusallyNeedsToDeclareException() {
new FileInputStream("/doesn'tMatter");
}
In the example the method should have declared throws FileNotFoundException, but with the #SneakyThrows annotation, it doesn't.
What actually happens behind the scenes is that lombok does the same trick as the high rated answer to this same question.
Mission accomplished!
We have a system that is possible to customise using groovy scripts and I've spotted a very strange effect on the type of exceptions throw from these scripts.
We have a groovy script with the following:
process {
throw new Exception("weeee")
}
Process is defined as a Closure in the base class of the script:
public abstract class ScriptBaseClass extends Script {
Closure process;
public void process( Closure code ) {
process = (Closure) code.clone();
}
}
In the Java class that actually runs the scripts we have the following method (omitted all the set up code as it doesn't seem relevant):
public void process() {
try {
script.process.call();
} catch (Exception e) {
logger.debug("exception thrown from groovy script", e);
throw e;
}
}
Note the process method here doesn't declare it throws any exceptions. However it quite clearly re-throws the Exception e that it caught. This code is valid, it compiles and runs quite happily. It throws the Exception as I wanted.
Does any one know how this is legal code? In theory I shouldn't be able to throw a checked exception out of a method that doesn't declare that it throws it.
It works because Java compiler (starting since Java 7) can determine re-thrown exception. For catch (Exception e) it thinks it's RuntimeException because there were no other (checked) exception declared in call().
You can read about it there, for example: https://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html
So this code compiles perfectly:
public void xxxxx() {
try {
System.out.println('Hi!'); //or anything else w/o declared exceptions
} catch (Exception e) {
throw e;
}
}
Java compiled sees that only RuntimeException could be caught here, so it doesn't ask you do declare anything.
But for this:
public void xxxxx() {
try {
throw new IOException(); //or anything that have declared checked exception
} catch (Exception e) {
throw e;
}
}
it will fail to compile, because IOException could be caught and re-thrown
Introducing closures or anything Groovy related is unnecessary complexity. The following is valid Java code:
public class Demo {
public void someMethod() {
try {
System.out.println("Hello");
} catch (Exception e) {
throw e;
}
}
}
Note that the following is not valid and will not compile:
import java.sql.*;
public class Demo {
public void someMethod() {
try {
Connection c = DriverManager.getConnection("", "", "");
} catch (SQLException e) {
throw e;
}
}
}
Groovy and the JVM don't really care about an exception being a checked one or not. Only the Java compiler cares about this here. In fact you can use the catch on any RuntimeException or its parent classes (of which Exception is one) without requiring it being declared as thrown from something called in the try-block. So it is fine by the compiler to catch Exception or Throwable even. Of course, from a program logic view it is an entirely different matter.
The javadoc example
try {
someMethodThatCouldThrowAnything();
} catch (IKnowWhatToDoWithThisException e) {
handle(e);
} catch (Throwable t) {
Throwables.propagateIfInstanceOf(t, IOException.class);
Throwables.propagateIfInstanceOf(t, SQLException.class);
throw Throwables.propagate(t);
}
is not very concrete. How would a real program look like? I don't really understand the purpose of the methods Throwables.propagateIfInstanceOf(Throwable, Class), propagate(), propagateIfPossible(). When do I use them?
The purpose of these methods is to provide a convenient way to deal with checked exceptions.
Throwables.propagate() is a shorthand for the common idiom of retrowing checked exception wrapped into unchecked one (to avoid declaring it in method's throws clause).
Throwables.propagateIfInstanceOf() is used to retrow checked exceptions as is if their types are declared in throws clause of the method.
In other words, the code in question
public void doSomething()
throws IOException, SQLException {
try {
someMethodThatCouldThrowAnything();
} catch (IKnowWhatToDoWithThisException e) {
handle(e);
} catch (Throwable t) {
Throwables.propagateIfInstanceOf(t, IOException.class);
Throwables.propagateIfInstanceOf(t, SQLException.class);
throw Throwables.propagate(t);
}
}
is a shorthand for the following code:
public void doSomething()
throws IOException, SQLException {
try {
someMethodThatCouldThrowAnything();
} catch (IKnowWhatToDoWithThisException e) {
handle(e);
} catch (SQLException ex) {
throw ex;
} catch (IOException ex) {
throw ex;
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
See also:
Checked versus unchecked exceptions
The case against checked exceptions
I have gone through the documentation of the Guava Throwables and I haven't found them really useful. Using throw new RuntimeException(e) is simpler to comprehend than Throwables.propagate(), in the scenario where you want to throw an unchecked exception wrapping a checked exception.
One scenario I can provide for anyone who'll find this useful is if you have a method wrapping any exceptions thrown, then this can be used to unwrap/cast the cause into specific exception.
Example: the get method in Guava's LoadingCache wraps all checked exceptions into ExecutionException. The documentation states that the exception can be inspected using getCause().
Here Throwables.propagateIfInstanceOf can be used to throw specific exceptions for the calling method to handle, if we know that cache.get() will throw those exceptions (maybe specific to LoadingCache, but if value is misisng, the cache tries to load a value which can throw checked exceptions).
public String getCacheValue(String key) throws SQLException{
try{
return cache.get(key);
}catch(ExecutedException ex){
Throwables.propagateIfInstanceOf(ex.getCause(), SQLException.class);
Throwables.propagate(ex);
}
}
i have question regarding chain exception
try{ } catch(Exception e) { throw new SomeException(); }
if i do like this
my eclipse will prompt error at line throw new SomeException();
stating "unhandled exception"
and i must put something like
try{ } catch(Exception e) {
try{ throw new SomeException(); } catch(Exception e){}
}
why must do like this
because tutorial that i read .example http://java.sys-con.com/node/36579 , does not have to do this
You'll need to declare that the method throws another exception, if the exception is a checked exception.
("The unchecked exceptions classes are the class RuntimeException and its subclasses, and the class Error and its subclasses. All other exception classes are checked exception classes." -- Java Language Specification, Second Edition, Section 11.2)
For example, rather than:
void someMethod {
try {
// Do something that raises an Exception.
} catch (Exception e) {
throw new SomeException(); // Compile error.
}
}
A throws needs to be added to the method declaration:
void someMethod throws SomeException {
try {
// Do something that raises an Exception.
} catch (Exception e) {
throw new SomeException(); // No problem.
}
}
It depends if SomeException is a checked exception or not. If it is (it extends Exception but not RuntimeException) then you have to declare it on the method or throw a RuntimeException instead.
This is what your code should look like:
...) throws SomeException {
....
try {
....
} catch (Exception e) {
throw new SomeException(e);
}
If some exception doesn't have a constructor which takes an exception, then do this:
throw (SomeException) new SomeException().initCause(e);
That way when the exception is ultimately caught, you know the root cause of the problem.
your method must declare that it may throw that exception. so, you must add:
throws SomeException {
at the end of your method's header.
You need to add "throws SomeException" to your method declaration. You need to specify any exception types that your method throws except for exceptions that descend from RuntimeException.