Best practices for passing same exception to call via stream - java

I have one method throwing MyOwnException, but we all know that it is suggested to wrap it with RunTimeException when we are calling within streams. So here is the implementation I have done:
package com.company;
import java.util.Arrays;
import java.util.List;
public class Main {
static class MyOwnException extends Exception {
}
public static void main(String[] args) throws MyOwnException {
// write your code here
List<String> input = Arrays.asList("bad", "ok");
try {
long i = input.parallelStream().map(s -> tryIfBadStringThrowExceptionIdentity(s)).count();
}
catch (RuntimeException re) {
String s = re.getMessage();
if(s.equalsIgnoreCase("MyOwnException"))
throw new MyOwnException();
}
}
private static String ifBadStringThrowExceptionIdentity(String s) throws MyOwnException {
if(s.equalsIgnoreCase("bad"))
throw new MyOwnException();
else return s;
}
private static String tryIfBadStringThrowExceptionIdentity(String s) {
try {
return ifBadStringThrowExceptionIdentity(s);
} catch (MyOwnException e) {
throw new RuntimeException("MyOwnException");
}
}
}
Passing string and then again creating exception back via the string, is it best practices, or you have some elegant solution to this? if this is best way, am I the only one started disliking Java? And by the way, why only RunTimeException is valid for Streams related exception, does it impact code speed converting string back to exception?

Do not use an existing exception type like RuntimeException that can have other causes and don’t rely on something as fragile as strings for identifying your issue. Just use a dedicated exception type for carrying an underlying checked exception to the initiator:
static class UncheckedMyOwnException extends RuntimeException {
UncheckedMyOwnException(MyOwnException original) {
super(original);
}
#Override
public MyOwnException getCause() {
return (MyOwnException)super.getCause();
}
}
public static void main(String[] args) throws MyOwnException {
List<String> input = Arrays.asList("bad", "ok");
try {
// do not rely on count() for processing code; starting with JDK 9 it will skip
// map operations not needed to determine the count
input.parallelStream().map(s -> tryIfBadStringThrowExceptionIdentity(s))
.forEach(System.out::println);
}
catch(UncheckedMyOwnException re) {
throw re.getCause();
}
}
private static String ifBadStringThrowExceptionIdentity(String s) throws MyOwnException {
if(s.equalsIgnoreCase("bad"))
throw new MyOwnException();
else return s;
}
private static String tryIfBadStringThrowExceptionIdentity(String s) {
try {
return ifBadStringThrowExceptionIdentity(s);
} catch(MyOwnException e) {
throw new UncheckedMyOwnException(e);
}
}
Note that this will throw the original exception, so it includes the actual origin in its stack trace. But when the exception happened in a worker thread, it will not include the initiator, i.e. the call chain that started the stream operation. To ensure that both parts are always included, you would have to use something like
catch(UncheckedMyOwnException re) {
MyOwnException withInitiator = new MyOwnException();
withInitiator.initCause(re.getCause());
throw withInitiator;
}
Using a dedicated unchecked exception type to carry a checked exception, is an established pattern, see for example UncheckedIOException.

Related

Determining which method throws exception

Below code catches an IOException , the first exception throw will be the one that is caught. To determine which method is throwing the IOException is the sole solution to wrap each method that throws an IOException in a try catch block ? I ask as my planned solution adds alot of try catch code and perhaps there is a cleaner solution to determine which method is throwing IOException ?
import java.io.IOException;
import java.net.SocketException;
public class Driver {
private static void te() throws IOException {
throw new java.net.SocketException("Connection Reset");
}
private static void te2() throws IOException {
throw new java.net.SocketException("Connection Reset 2");
}
private static void te3() throws IOException {
throw new java.net.SocketException("Connection Reset 3");
}
public static void main(String args[]) {
try {
Driver.te();
Driver.te2();
Driver.te3();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The answer depends on your required logic. If the treatment of your exception is supposed to be different depending on which method threw the exception, (meaning that within catch you will need to write different error handling code depending on which method threw the exception, then you do need to wrap each method invocation into separate try-catch. But if the error handling is the same then your code is fine (except that usually, you print your stacktrace into a log file) and you would be able to figure out which method threw the exception by reading your stacktrace as a human user. But then again if the error handling is the same then your code doesn't need to know which specific method threw the exception.
I don't know why you are doing something like that, and surely a real situation would be far away from this code fragment but, in "real life" I would consider extending IOException: so you will have a single try with three catches in the main method. Do you like this solution?
Create a custom exception for each method:
class TeException extends IOException { /* constructor */ }
private static void te() throws TeException {
throw new java.net.SocketException("Connection Reset");
}
Then it is fairly easy to distinguish among multiple exception with separate catch blocks:
try {
Driver.te();
Driver.te2();
Driver.te3();
} catch (TeException e) {
e.printStackTrace();
} catch (Te2Exception e) {
e.printStackTrace();
} catch (Te3Exception e) {
e.printStackTrace();
}
An alternative might be to read the method that failed with the stacktrace:
final String failedMethodName = e.getStackTrace()[0].getMethodName());
You can do it as follows:
try {
Main.te();
Main.te2();
Main.te3();
} catch (Exception e) {
System.out.println(e.getStackTrace()[0].getMethodName());
}
In a real life scenario, you would probably be writing something to a log file in the case of an exception. For example:
public class Driver {
// assuming slf4j
private static Logger logger = LoggerFactory.getLogger(Driver.class);
private static void te() throws IOException {
logger.error("exception happened in te()");
throw new java.net.SocketException("Connection Reset");
}
}
Then, to figure out which methods threw exceptions, you would only need to open the log file and check.

return dummy interface instance?

I have example code from a third party related to some API. It doesn't run because of an unhandled exception in a return statement.
The problem: The return type is an interface whose instances are always created with complicated factories (assume I do not have access to these). Thus even if I handle the exception in the stupid do-nothing way, I still can't return a valid dummy object.
public FunnyInterface calculateSomething()
{
return builder.someFunnyInterface(); // throws Exception
}
To get this code to run, is there anything I can do not involving:
modifying the code along the route where calculateSomething() is called,
finding a builder in the API that won't throw an Exception, or
manually writing a dummy class implementing the interface
?
Since you wrote that you can't call the builder, I guess that you are not interested in the value of type FunnyInterface, so just return null.
public FunnyInterface calculateSomething() {
try {
return builder.someFunnyInterface(); // throws Exception
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Or just
public FunnyInterface calculateSomething() {
return null;
}
I'd recommend a simple rethrow with wrapped in a RuntimeException so you don't need to declare a checked exception:
// Dummy mockup interface + function
public static interface FunnyInterface {}
public static FunnyInterface builder_someFunnyInterface() throws Exception { return null; }
public FunnyInterface calculateSomething() {
try {
return builder_someFunnyInterface(); // throws Exception
} catch (Exception e) {
throw new RuntimeException(e);
}
}
I would not return null. If you don't have a meaningful way to handle the error, propagate it upwards to a level that does have a meaningful way to handle the error. If you really do want to return null/empty, then use Optional, otherwise throwing an unchecked RuntimeException is preferable.

JUnit handling of RuntimeException (specifically)

I tend to throw as many checked Exceptions up as possible: it declutters the code (and I regard checked Exceptions as a dubious aspect of Java). I tend to use them when "refining" code.. i.e. when it makes sense for the particular context.
This approach gets slightly complicated when overriding superclass/interface methods which don't throw the requisite Exception, and therefore I tend to do this:
#Override
public void close() {
try {
_close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
where _close is a private method which does all the business.
The problem when it comes to JUnit, if you actually want to test something where an exception is thrown by _close() is that the resulting RuntimeException seems to be handled by JUnit in an "unconditional" way: it seems always to stop the test with a failure message... even if you actually catch and deal with it in a try .. catch!
There is a sort of "workaround" for this which I've found (the CUT class closes all its closeableComponents when it is closed):
#Test (expected = RuntimeException.class)
public void errorFlagShouldBeSetIfAnyCloseablesThrowExceptionWhenCUTCloses() throws Exception {
Closeable spyCloseable = spy( new Closeable(){
#Override
public void close() throws IOException {
throw new IOException( "dummy" );
}});
spyCUT.addCloseableComponent( spyCloseable );
Exception blob = null;
try{
spyCUT.close();
}catch( Exception e ){
blob = e;
}
assertThat( spyCUT.getErrorFlag() ).isTrue();
if( blob != null ){
throw blob;
}
I.e. if you don't have this expected setting you always get a test failure (because of the RuntimeException "ignoring" the try .. catch). But in order to satisfy the expected you then have to rethrow the RuntimeException at the end of the test...
... is there any way of varying JUnit's handling of RuntimeExceptions?
Something must be wrong in your setup. JUnit does not have any such special handling for runtime exceptions.
I put together this MCVE; and it passes.
static class CUT {
void close(Closeable _close) {
try {
_close.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
#Test
public void test() throws Exception {
Closeable spyCloseable = Mockito.spy(new Closeable() {
#Override
public void close() throws IOException {
throw new IOException("dummy");
}
});
Exception blob = null;
try {
new CUT().close(spyCloseable);
fail("should have thrown");
} catch (Exception e) {
blob = e;
}
assertThat(blob.getMessage(), is("java.io.IOException: dummy"));
}
It is not exactly what you have up there; but "close enough" in my mind.
Long story short: your answer is coming from some other place. I suggest: do the same as I did: create a true mcve; and work your way from there!

Issue with Exception type handling when not throwing them - wanting a more generic version of multi-catch

Sorry for the TL;DR, but I feel like it needs some explanation or it will be misunderstood.
I have a method that makes a call to (generally external) code which I expect to sometimes throw a RuntimeException, and uses futures which can throw InterruptedException or ExecutionException, and I want to be able to return an ordered set of returned values to from the call up until the exception was thrown, and the exception that was thrown. I wrote something that works, but unfortunately, the way the code looks makes me feel like I'm doing something wrong. What I think I really want is multi-catch to be a more generic concept that. That would allow pretty clean code to solve it, kind of like this:
public class SomeResults {
private final Set<SomeReturnType> valuesReturned;
private final #Nullable RuntimeException | ExecutionException | InterruptedException exception;
public SomeResults(Set<SomeReturnType> valuesReturned, RuntimeException | ExecutionException exception {
this.valuesReturned = valuesReturned;
this.exception = exception;
}
public Set<SomeReturnType> getValuesReturned() {
return valuesReturned;
}
public #Nullable RuntimeException | ExecutionException | InterruptedException getException();
}
And have a method that wraps up making the calls to the external code
...
generateResults(Bar bar) {
// Setup code
Set<SomeReturnType> valuesReturned = new LinkedHashSet<>();
...
// loop
{
// stuff
... // exceptions in this method should throw except for this one external code call
try {
valuesReturned.add(externalCodeCallGetSomeReturnValue(bar))
}
catch( RuntimeException | ExecutionException | InterruptedException e) {
return new MyResults(valuesReturned, e)
}
...
}
return new MyResults(valuesReturned, (RuntimeException | ExecutionException | InterruptedException) null);
}
And subsequently do
SomeResults myResults = foo.generateResults(new Bar());
if(myResults.getException() != null) {
throw(myResults.getException);
}
Etc. Note that I do note always want to immediately rethrow the exception - it depends on who is using these results what they will want to do with them. I might do something like
try {
SomeResults myResults = foo.generateResults(new Bar());
Foobar Foobar = new Foobar(myResults);
}
catch(Exception e) {
// I don't want to see any exceptions from externalCodeCallGetSomeReturnValue(bar) here
...
}
Of course, I could let the exception get thrown in the function that generates results, instead of catching the exception and returning it as a result. This has two pretty big issues:
1. Now returning the set of values is going to be awkward - I could perhaps pass in a Set to the method that needs to "return" results and it modifies that set instead of returning a set. That allows the set to be up to date when the exception is returned. Eg
generateResults(Bar bar, Set<SomeReturnType> orderedListForMeToWrite) throws ExecutionException, InterruptedException
What if code surrounding the external method call throws a runtime exception? Now I have no easy way of distinguishing if the exception call was from the actual call to the external code, or something else! I actually ran into this issue when attempting this design. The code threw IllegalArgumentException from somewhere else, and my code handling treated it as if it had been thrown from SomeReturnType externalCodeCallGetSomeReturnValue(Bar bar). This seemed like a code health issue, which is why I moved away from this solution.
The solution I went with is to just store the exception as an Exception. However, I hated losing that type information. With no additional code work, if something wanted to throw it, it will have to declare "throws Exception", which is not good, similar code health issues there. Is there a good way to handle this situation?
What I ended up doing to get it to work the way I wanted it to is as follows:
public static class SomeResults {
private final Set<SomeReturnType> orderedReturnValues;
private final #Nullable Exception exception;
AsyncEchoesResult(Set<SomeReturnType> responses) {
this.orderedResponses = responses;
this.exception = null;
}
AsyncEchoesResult(Set<SomeReturnType> responses, RuntimeException exception) {
this.orderedResponses = responses;
this.exception = exception;
}
AsyncEchoesResult(Set<SomeReturnType> responses, ExecutionException exception) {
this.orderedResponses = responses;
this.exception = exception;
}
AsyncEchoesResult(Set<SomeReturnType> responses, InterruptedException exception) {
this.orderedResponses = responses;
this.exception = exception;
}
public Set<SomeReturnType> getResponses() {
return orderedResponses;
}
public #Nullable Exception getException() {
return exception;
}
public void throwExceptionIfExists() throws ExecutionException, InterruptedException {
try {
throw (exception);
}
catch (RuntimeException | ExecutionException | InterruptedException e) {
throw e;
}
catch (Exception e) {
throw new RuntimeException("Unexpected exception type in SomeResults",e);
}
}
}
Obviously, this is pretty ugly. If I hate the constructors as they are I can easily enough replace them with a single one that takes an Exception, but that weakening the type-checking to only the runtime call of throwException(). Anyway, are there alternatives that work better? Note that I'm using with JDK 7 so while JDK 8 answers would be interesting, that won't fix it for what I'm working on.
Since Java doesn’t allow declare a variable as “one of these types” you have to encapsulate the exception using the only construct which supports such a type set: a piece of code throwing that exception.
Consider the following type definitions:
interface ReThrower {
void reThrow() throws RuntimeException, ExecutionException, InterruptedException;
}
static class MyResult
{
private final Set<SomeReturnType> valuesReturned;
private final #Nullable ReThrower exception;
public MyResult(Set<SomeReturnType> valuesReturned, ReThrower exception) {
this.valuesReturned = valuesReturned;
this.exception = exception;
}
public Set<SomeReturnType> getValuesReturned() {
return valuesReturned;
}
public void reThrowException()
throws RuntimeException, ExecutionException, InterruptedException
{
if(exception!=null) exception.reThrow();
}
}
Then you can create a MyResult like this:
MyResult generateResults(Bar bar) {
// Setup code
Set<SomeReturnType> valuesReturned = new LinkedHashSet<>();
// …
// loop
{
// stuff
// … exceptions in this method should throw except for this one external code call
try {
valuesReturned.add(externalCodeCallGetSomeReturnValue(bar));
}
catch( RuntimeException | ExecutionException | InterruptedException e) {
// In Java 8 you would say: new MyResult(valuesReturned, ()->{ throw e });
return new MyResult(valuesReturned, new ReThrower() {
public void reThrow()
throws RuntimeException, ExecutionException, InterruptedException {
throw e;
}
});
}
//...
}
return new MyResult(valuesReturned, null);
}
Note that the inner class (or lambda expression in Java 8) implicitly stores the exception and that that implicit variable has the desired “one of the listed exception type”. Then, you can safely re-throw the exception:
MyResult results = new MultiCatchAndStore().generateResults(new Bar());
try
{
results.reThrowException();
} catch(RuntimeException | ExecutionException | InterruptedException ex)
{
// handle, of course, you could also have separate catch clauses here
}

Catching an Exception from a called Method

This is something that's been bugging me for a while with regards to Program Flow.
I wanted to know if it's possible to catch an error from a Method in order to stop it from executing the Method that would normally follow it like the example bellow that I can't get to work.
public class MyClass {
public static void main(String[] args) {
// this method catches an exception and stops running
method01();
// this method will continue anyway which I don't want
method02();
};
};
I would normally have a static int variable that will initialize as 0 when the program is run and then if a method ever catches an exception it will increment that int and each method will only run if the int is 0.
This works but I was just wondering if I could replace the int shindig with exception handling.
Can you try:
try {
method01()
} catch (final Exception e) {
// do something
return; ///stop processing exit
}
the method01 will throw Exception:
private void method01() throws Exception {
// something
}
If you only want to terminate the whole program in case of an exception you just need to throw a RuntimeException without any further declaration. There are also specialized sub classes for explicit types of exceptions, like NullPointerException or IllegalStateException. See the "Direct Known Subclasses" section in the JavaDoc.
public class MyClass {
public static void main(String[] args) {
method01();
method02(); //method02 won't be called in case of an exception
}
private static void method01() {
// ...
if (true) // something goes wrong
throw new RuntimeException();
// further code won't be executed in case of an exception
}
private static void method02() {
System.out.println("method02 called");
}
}
Optionally it is possible to handle the exception with a try-catch-block:
public static void main(String[] args) {
try {
method01();
method02(); // method02 won't be called in case of an exception
} catch (Exception e) {
System.err.println("something went wrong");
}
}
// other code keeps unchanged...
If you want to enforce exception handling, you have to throw a subclass of Exception that is not derived from RuntimeException. But those exceptions have to be declared within the method Signature.
private static void method01() throws IOException {
throw new IOException();
}
You put method01 and method02 in to same try block:
public class MyClass {
public static void main(String[] args) {
try {
// This method catches an exception and stops running.
method01();
// This method will not continue if method01 have exception.
method02();
} catch (Exception e) {
e.printStackTrace();
}
}
// declare method01, method02, others...
}
Notice: You have mistakes at the end of code block ( }; }; )
Depends on what your method really does.
If your program should continue working also when an exception arise (e.g. NumberFormatException when parsing an input or in general a checked exception) a lot of people will suggest you to not use exception for flow control, but IMHO in very well defined cases (like NumberFormatException) the flow CAN be controlled by try catch statements and exceptions, it's really up to you.
A way to do so is to use the method returned parameter (also #Nikola answer works in this way, the point is to use the catch part of a try catch as flow control):
public class MyClass {
public static void main(String[] args) {
if(method01()) method02();
};
};
public boolean method01(){
try{
//some business
}catch(MyCheckedException e){
e.printStackTrace();
return false;
}
return true;
}
NB: You should use this approach only in well defined situations! If a file CAN be absent in a directory while opening it (checked FileNotFoundException), you COULD use this approach. If the file SHOULD be there and its not, the exception MUST stop the program.

Categories

Resources