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.
Related
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!
I'm studying Java by examples in a book.
I wrote below code and got "Unhandled exception type IOException"
WHY? and HOW could I solve this. Should I declare IOException class?
import java.nio.file.*;
public class JavaIO {
public static void main(String[] args) {
String dirString = "C:/Users/USER/Desktop/Test/Files";
Path dirPath = Paths.get(dirString);
if(Files.notExists(dirPath)){
Files.createDirectory(dirPath);
}
System.out.println("Err");
System.exit(1);
}
}
Because Files.createDirectory() may throw java.io.IOException and you did neither catch it nor declare to throw it.
Catch the exception to handle errors
import java.nio.file.*;
public class JavaIO {
public static void main(String[] args) {
String dirString = "C:/Users/USER/Desktop/Test/Files";
Path dirPath = Paths.get(dirString);
if(Files.notExists(dirPath)){
try{
Files.createDirectory(dirPath);
} catch(java.io.IOException e){
System.out.println("createDirectory failed:" + e);
}
}
System.out.println("Err");
System.exit(1);
}
}
or add declaration to throw it to ignore its possibility to be thrown.
import java.nio.file.*;
public class JavaIO {
public static void main(String[] args) throws java.io.IOException {
String dirString = "C:/Users/USER/Desktop/Test/Files";
Path dirPath = Paths.get(dirString);
if(Files.notExists(dirPath)){
Files.createDirectory(dirPath);
}
System.out.println("Err");
System.exit(1);
}
}
Files.createDirectory(Path dir, FileAttribute<?>... attrs) throws IOException which is a checked Exception; either catch it or modify main to indicate it might be thrown. Something like,
public static void main(String[] args) throws IOException {
or use a try-catch and catch the IOException like
if(Files.notExists(dirPath)){
try {
Files.createDirectory(dirPath);
} catch (IOException e) {
e.printStackTrace();
}
}
Look up a Try Catch and place the parts of your code that are dealing with the file inside it. This will handle and report exception if the file cannot be created or the location doesn't exist.
When you are working with files or performing an IO operation in Java, there is a chance that you will not be able to access the files or resource for various reasons, This will throws a Exception condition on lines of FIleNotFound or IO operation cannot be performed. This Exception need to be handled as it comes under "checked" exception in Java. Simply said you need to either handle this case yourself or let the child classes do it using Throws, throw or try/catch block.
Hence with "Unhandled exception type IOException" message Java is asking you to do the same.
So I'm working on a little project in Java and I've come down to the main method and I'm unsure how I should handle try-catching exceptions correctly.
Should I be:
Try-catching specific lines of code that I know will probably throw an exception?
Like:
public class Stuff {
public static void main(String[] args) {
try {
// code that will probably throw exception 1 or 2
} catch (exception1 e) {
// handle exception 1
} catch (exception2 e) {
// handle exception 2
}
//rest of code that probably won't throw any exceptions
}
}
OR
Try-catching the whole main method even if some of the code in the try block will not throw an exception? Like:
public class Stuff {
public static void main(String[] args) {
try {
// code that will probably throw exception 1 or 2
// rest of code that probably won't throw any exceptions
} catch (exception1 e) {
// handle exception 1
} catch (exception2 e) {
// handle exception 2
}
}
}
One thing to consider is whether or not the code running after the catch block would still be valid if an exception was thrown. For example, consider the following method:
private void readFile()
{
List<String> lines = null;
try
{
lines = Files.readAllLines(Paths.get("/to/my/file.txt"));
}
catch (IOException e)
{
// log exception...
}
for (String line : lines)
{
System.out.println(line);
}
}
If readAllLines throws that IOException, then the code after the catch block will throw a NullPointerException.
There's a bigger question of deciding when to catch vs re-throw an exception. I answer it by asking myself this question:
"Can my method fulfill its contract if this exception is thrown?"
YES: Handle the exception and continue to fulfill the method's contract.
NO: Re-throw the exception (either in throws clause or wrap in a more appropriate exception type).
For example, with this method,
public static List<String> readAllLines(Path path) throws IOException
if the file does not exist, it cannot return a list of the lines of the file, so it throws an IOException.
On the other hand, this method
public static boolean deleteIfExists(Path path) throws IOException
does not throw an exception if the file does not exist (it instead returns the boolean to tell you what happened). One way to think of the contract of this method is, "after this method executes, there will not be a file at path". So in this case, if the file does not exist, the contract is still fulfilled.
That depends - should the non-exceptional code be executed if either exception is raised? This isn't a "best practices" question, this is a "what are your specifications?" question.
Suppose your code looks like this:
String someValue;
try {
someValue = parseSomething();
} catch (ParseFailureException e) {
someValue = defaultValue;
}
// Continue, possibly using the default value
In a case like this, you should wrap only the single line. On the other hand, maybe your code looks like this:
String someValue;
try {
someValue = parseSomething();
} catch (ParseFailureException e) {
log.fatal("The universe is crashing! Run for your lives!");
System.exit();
}
// Continue, assuming that parsing succeeded
In that case, it's a stylistic choice. Either approach is valid, though with such an extreme failure as in this example it might be better to simply declare that the method throws something and forget the try/catch entirely. In fact, whatever your handling code is, if the only thing left for your method to do after it is to bail out, you should consider omitting the try/catch and using a throws clause instead.
This third case, however, is objectively wrong:
String someValue;
try {
someValue = parseSomething();
} catch (ParseFailureException e) {
log.info("something strange happened");
// Don't bother the calling code with the exception, it can't handle it.
}
// Continue, assuming that parsing succeeded
In a case like that, the continuation code must go inside the try block.
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.
I have a Java Program where I get data from a different source. some times while reading I see Exception and the program is exiting.
Mine is in a program that runs every 10minutes.
Public static void main(Strings[] args)
{
...readsource();
}
Private static void readsource() throws IOException
{
...
}
Issue:
I am able to get/See the Exception. But I want the program to continue
To that what is the best logic? I dont see try-catch-finally also is not addressing ..I want the program to continue even after seing the exception (I mean the next iteration should continue). This looks to be a Basic issue not sure how to address this...
Then you need to catch the exception, which you are currently not doing.
try {
readsource();
} catch (IOException e) {
// do something, never catch an exception and not do anything
}
//continue.
Note that exceptions usually indicate something is wrong. Unless you are going to do something about the exception, it might be better to fix the condition causing the exception....
You have to provide an error handler in your method, i.e. surround the call to readsource() with a try-catch block.
public static void main(Strings[] args)
{
try{
...readsource();
}
catch(IOException ioe){
//handle the error here,e.g don't do anything or simply log it
}
}
If you don't rethrow the exception in the catch block, execution will fall off the end of the catch block and continue as if there was no exception.
If you mean you'd like to recall the method wether an Exception was thrown or not just place this in a while loop i.e:
Public static void main(Strings[] args)
{
boolean run=true;
while(run) {
try {
System.out.print("Hello,");
readsource();
throw new IOException();
if(1==2)run=false;//stop the loop for whatever condition
} catch(IOException ioe) {
ioe.printStackTrace();
}
System.out.println(" world!");
}
}
}
Private static void readsource() throws IOException
{
...
}