I am trying to implement lambda expression for constructor. My constructor can throw an IllegalArgumentException. I tried different ways. First way is just calling lambda expression:
catchThrowable(() -> new SomeClass(testVar1, null, testVar2));
It works perfectly fine, I can catch Exception and then parse it. The problem occurs when I try to use my own interface:
interface SomeClassFactory{
SomeClass create (String testVar1, String persId, String testVar2) throws IllegalArgumentException;
}
SomeClassFactory factory = SomeClass::new;
and then I use it as:
catchThrowable((ThrowableAssert.ThrowingCallable) factory.create(testVar1, null, testVar3));
But the last line of code does not catch any exceptions, my code gives runtime exception and stops. Can you please explain why it happens and, if possible, how to fix it?
What happens is that factory.create(...) is executed and the result is passed to catchThrowable, so the exception is actually thrown before the catchThrowable execution.
To fix it, you can either use a lambda:
catchThrowable( () -> factory.create(testVar1, null, testVar3));
or you can define your own interface extending ThrowableAssert.ThrowingCallable:
interface SomeClassFactory extends ThrowableAssert.ThrowingCallable {
#Override
SomeClass call() throws IllegalArgumentException;
}
which would allow you to call:
catchThrowable(factory);
Note that the custom interface does not allow parameters on the overridden method.
Related
I have following issue.
I'm working within a method 1 and this method 1 should return an object of a certain class.
For my return statement I call another method 2 (which of course returns an object of said class). Though this other method 2 throws an exception. How should I write my return statement in my initial method 1?
Like this?
public class testClass {
public testClass() {
}
public <T> T method1(parameter1, ...) {
if(parameter1) {
return () -> {
try {
method2(parameter1, parameter2...);
}
catch (CloneNotSupportedException ex) {
System.err.print("Error while cloning programmer");
}
};
} else {
return null;
}
}
But I guess if I do this it will only return null?
Should i put the return null after the last bracket? Or should i write this in a totally different way?
Edit. You wrote
Basically normally the exception should never be thrown
That's a perfect usecase for a RuntimeException. It's basically a transparent exception. Users of your code won't see it, but it will appear like a wild Pokemon when something extraordinary happens, and will make your application come to a stop, giving you a chance to fix it.
Your standard code flow won't be affected, and you'll avoid returning a null value.
Lambda expressions aren't allowed to throw checked Exceptions.
CloneNotSupportedException extends Exception.
Now, you have two options
Handle the Exception in-place, as you did
Propagate the Exception by wrapping it in a RuntimeException
return () -> {
try {
method2(parameter1, parameter2...);
} catch (final CloneNotSupportedException e) {
throw YourCustomRuntimeException("Error while cloning", e /* Original cause */);
}
};
This depends on the usecase, but I think CloneNotSupportedException signals a bug, which should be evident to you, developer. So let it surface.
The custom Exception just need to extend RuntimeException, and, maybe, provide additional fields to store relevant data.
YourCustomRuntimeException extends RuntimeException { ... }
Do not throw the base RuntimeException, use custom ones.
Observable.fromCallable() is great for converting a single function into an Observable. But how do you handle checked exceptions that might be thrown by the function?
Most of the examples I've seen use lambdas and "just work". But how would you do this without lambdas? For example, see the quote below from this great article:
Observable.fromCallable(() -> downloadFileFromNetwork());
It's a one-liner now! It deals with checked exceptions, no more weird Observable.just() and Observable.error() for such easy thing as deferring code execution!
When I attempt to implement the above Observable without a lambda expression, based on other examples I've seen, and how Android Studio auto-completes, I get the following:
Observable.fromCallable(new Func0<File>() {
#Override
public File call() {
return downloadFileFromNetwork();
}
}
But if downloadFileFromNetwork() throws a checked exception, I have to try-catch it and wrap it in a RuntimeException. There's got to be a better way! How does the above lambda support this?!?!
Rather than using a Func0 with Observable.fromCallable(), use Callable. For example:
Observable.fromCallable(new Callable<File>() {
#Override
public File call() throws Exception {
return downloadFileFromNetwork();
}
}
Since Callable's method call() throws Exception, you don't have to wrap your function in a try-catch! This must be what the lambda is using under the hood.
You could also do this to return checked exceptions:
return Observable.fromCallable(() -> {
sharedPreferences.edit()
.putString(DB_COMPANY, LoganSquare.serialize(
CompanyDBTransformation.get(user.getCompany())
))
.apply();
return user;
}).onErrorResumeNext(
throwable -> Observable.error(new CompanySerializationException(throwable))
);
So here I'm serializing taking the IOException risk, and I'm giving back a more descriptive description.
I have dozens of methods that I want to wrap with the same try/catch handling. I think lambdas can help me out here, but I'm having difficulty figuring out the syntax.
Here's the context of what I'm trying to achieve.
method1(..., result -> method2(result, ...));
method2 is a handler for the results of method1. I would like to wrap method2 with a common try/catch statement that's common to a large number of handlers, without having to copy/paste the statement to all handlers.
Note: These are unchecked exceptions.
*edit - Concrete example of what I'm trying to do.
I'm using Vert.x, and they use a common design pattern of Handlers. Here's an example of their SQL interface
query(String sql, Handler<AsyncResult<ResultSet>> resultHandler)
Handler is a simple 1 function interface:
void handle(E event)
So basically, the query defined in "sql" is executed, and the results are sent to the resultHandler. Here would be an example of this in use:
connection.query("SELECT * from table1", asyncResult -> {
// do something with results
}
The above uses their documentation's standard coding style. I personally prefer to handle the results in named functions various reasons, so it changes to:
connection.query("SELECT * from table1", asyncResult -> method1(asyncResult));
void method1(AsyncResult<ResultSet> asyncResult) {
// do something with results
}
I do not have control over the query() interface, so I'm stuck with this pattern. I'm not sure if Tagir's solution will work in this context, but I'll play around with it in the morning.
*edit2 - I should note that I'm trying to wrap method1 in the above example in the exception wrapper, so ideally, I'd add the wrapper call inside the query() call. So what I'm looking for is something like:
connection.query("SELECT * from table1", wrap(asyncResult -> method1(asyncResult)));
Obviously, I can't use it that way, because it'll evaluate the original lambda as a parameter, but conceptually, that's where I want the wrapping to be added.
You may use Runnable functional interface to implement the method which handles exceptions:
public static void handleExceptions(Runnable r) {
try {
r.run();
}
catch(RuntimeException ex) {
ex.printStackTrace();
}
}
And call it like this:
handleExceptions(() -> method2(foo, bar));
If your method2 produces a result, you should determine what will be the default result in case if exception occurred (and you don't rethrow it in the handler). You may use the Supplier functional interface for such case:
public static <T> T handleExceptions(Supplier<T> r, T defaultValue) {
try {
return r.get();
}
catch(RuntimeException ex) {
ex.printStackTrace();
return defaultValue;
}
}
And call like this:
// set result to null if exception occurred
result = handleExceptions(() -> method2(foo, bar), null);
Or
// do not modify the result if exception occurred
result = handleExceptions(() -> method2(foo, bar), result);
Is there a way to annotate a method so all exceptions thrown are converted to runtime exception automagically?
#MagicAnnotation
// no throws clause!
void foo()
{
throw new Exception("bar")'
}
Project Lombok's #SneakyThrows is probably what you are looking for. Is not really wrapping your exception (because it can be a problem in a lot of cases), it just doesn't throw an error during compilation.
#SneakyThrows
void foo() {
throw new Exception("bar")'
}
You can do this with AspectJ. You declare a joinpoint (in this case invocation of the method foo) and 'soften' the exception.
Edit To elaborate a bit on this:
Say you have the following class Bar:
public class Bar {
public void foo() throws Exception {
}
}
...and you have a test like this:
import junit.framework.TestCase;
public class BarTest extends TestCase {
public void testTestFoo() {
new Bar().foo();
}
}
Then obviously the test is not going to compile. It will give an error:
Unhandled exception type Exception BarTest.java(line 6)
Now to overcome this with AspectJ, you write a very simple aspect:
public aspect SoftenExceptionsInTestCode {
pointcut inTestCode() : execution(void *Test.test*());
declare soft : Exception : inTestCode();
}
The aspect basically says that any code from within a Test (i.e.: a method that starts with "test" in a class that ends in "Test" and returns 'void') that throws an exception should be accepted by the AspectJ compiler. If an exception occurs, it will be wrapped and thrown as a RuntimeException by the AspectJ compiler.
Indeed, if you run this test as part of an AspectJ project from within Eclipse (with AJDT installed) then the test will succeed, whereas without the aspect it won't even compile.
No way to do that, at least for now I use workaround like this (simplified):
#SuppressWarnings({"rawtypes", "unchecked"})
public class Unchecked {
public static interface UncheckedDefinitions{
InputStream openStream();
String readLine();
...
}
private static Class proxyClass = Proxy.getProxyClass(Unchecked.class.getClassLoader(), UncheckedDefinitions.class);
public static UncheckedDefinitions unchecked(final Object target){
try{
return (UncheckedDefinitions) proxyClass.getConstructor(InvocationHandler.class).newInstance(new InvocationHandler(){
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (target instanceof Class){
return MethodUtils.invokeExactStaticMethod((Class) target, method.getName(), args);
}
return MethodUtils.invokeExactMethod(target, method.getName(), args);
}
});
}
catch(Exception e){
throw new RuntimeException(e);
}
}
}
And the usage looks like:
import static ....Unchecked.*;
...
Writer w = ...;
unchecked(w).write(str, off, len);
The trick is that interface is "never finished" and everytime I need unchecked method somewhere, I'll wrap that object into unchecked and let IDE generate method signature in interface.
Implementation is then generic (reflective and "slow" but usually fast enough)
There are some code post-processors and bytecode-weavers but this was not possible (not even aop or other jvm based language) for my current project, so this was "invented".
I think it is possible with bytecode re-engineering, customized compiler or perhaps aspect oriented programming1. In the contrary to Java, C# has only unchecked exceptions2.
May I ask why you want to suppress the checked exceptions?
1 according to Maarten Winkels this is possible.
2 and they are thinking about introducing checked ones, according to some Channel 9 videos.
Edit: For the question: It is possible in the sense that you can annotate your methods to flag them to be a candidate for checked exception suppression. Then you use some compile time or runtime trick to apply the actual suppression / wrapping.
However, as I don't see the environment around your case, wrapping an exception in these ways might confuse the clients of that method - they might not be prepared to deal with a RuntimeException. For example: the method throws an IOException and your clients catches it as FileNotFoundException to display an error dialog. However if you wrap your exception into a RuntimeException, the error dialog gets never shown and probably it kills the caller thread too. (IMHO).
The Checked exceptions are responsability of the method implementation.
Take very very carefully this fact. if you can do not use workaround artifacts like that.
You can do this in any case via use of the fact that Class.newInstance does not wrap an Exception thrown by the no-arg constructor in an InvocationTargetException; rather it throws it silently:
class ExUtil {
public static void throwSilent(Exception e) { //NOTICE NO THROWS CLAUSE
tl.set(e);
SilentThrower.class.newInstance(); //throws silently
}
private static ThreadLocal<Exception> tl = new ThreadLocal<Exception>();
private static class SilentThrower {
SilentThrower() throws Exception {
Exception e = tl.get();
tl.remove();
throw e;
}
}
}
Then you can use this utility anywhere:
ExUtil.throwSilent(new Exception());
//or
try {
ioMethod();
} catch (IOException e) { ExUtil.throwSilent(e); }
By the way, this is a really bad idea :-)
I use the completion / template system of Eclipse to wrap any block of code easily.
Here is my template :
try { // Wrapp exceptions
${line_selection}${cursor}
} catch (RuntimeException e) { // Forward runtime exception
throw e;
} catch (Exception e) { // Wrap into runtime exception
throw new RuntimeException(
"Exception wrapped in #${enclosing_method}",
e);
}
I have a method that is going to the DB so all our JDBC stuff in the DAO method is inside a try/catch block. It is catching SQLException
When I write a test case against this method and if a SqlException occurs then my testcase does not say 'caused an error'. it just goes on its merry way.
However, If I dont catch the SqlException in the DAO method but add throws SqlException to the method instead then my test case says 'caused an error' and shows me the error that happened. (this is what I want).
When I try adding throws SqlException along with the method catching the SqlException then also my test case does not say 'caused an error'.
what is the way around it? one is to have try/catch block inside my test case but even if I do this my Junit test case does not say 'caused an error' though the exception IS posted to standard output.
...but besides that anything else?
My IDE is Netbeans. this is where I run the test cases.
Code:
public class MyDaoClass {
Connection con;
public MyDaoClass (Connection connection)
{
this.con = connection;
}
public SomeObject someMethod (String id)
{
try{
Connection con = this.con;
CallableStatement cs = con.prepareCall("{call some_sp_name (?)}");
cs.setString (1, id);
cs.execute()//imagine an error happens here
ResultSet rs = cs.getResultSet()
...
....
//return SomeObject...
}
catch (SqlException e) //If I remove this and add 'throws SQLException to method then everything is ok
{
log.error(e.getMessage());//i dont have access to log object in test case
}
}
}
public class MyTestSuite extends TestCase
{
//populate local connection
public void testSomeMethod () throws SQLException
{
MyDaoClass myd = new MyDaoClass(connection);
SomeObject s = myd.someMethod("blah");
assertEquals (s.getFirstName(), "pepe");
}
}
All checked exceptions in Java must be declared in the method specification. SqlException is a checked exception, so if you want to throw it, you must include it in the specification.
If you want to throw an exception, but you can't change the method specification, you need to use an unchecked exception, like RuntimeException. It will also cause JUnit to show the error that happened.
The Java Tutorials: Exceptions is an excellent reference on this topic.
If you add throws SQLException to the method, then you don't have to try-catch it anymore.
And yes, you can catch and throw an exception:
try {
// some code
}
catch (SomeException e) {
throw e;
// or,
// throw new SomeOtherException();
}
JUnit doesn't care what you write to standard output. If the exception leaks out of your method, then JUnit takes notice.
If you catch the exception inside your method, then it's correct behavior for the exception not to come out of your method, because it was (we hope!) handled there. So a passing test is a Good Thing.
What you should be testing for is whether your method is producing the correct result (whatever that may be) even in circumstances when an exception is thrown (and handled).
that is not the full code is it? the compiler would complain that someMethod is not always returning a value.
If you want to keep the method as is, then at least add "return null;" after the try/catch.
That way, if an SQLException occurs, then assertEquals should throw NullPointerException which should work on your TestCase.
Side advice, i would check if connection is not null before using it.
Instead of re-throwing the exception, you can also return a null reference instead of an empty or incomplete object. Your callers must check for null's and handle the case when the DAO fails to load the object.
Alternatively, you can stub the log object in your JUnit test and inject it into the DAO via an alternative constructor. Your stubbed logger subclass can deliver the message to your test for inspection.
In addition to what Chip Uni said above re: Runtime exceptions to not need to be declared,
you should also note that exceptions can be nested, i.e.
catch (SqlException e)
{
throw new RuntimeException(e);
}
This will throw a RuntimeException that contains an SqlExceotion.