Java игнорирование ошибок

I have the following code:

TestClass test=new TestClass();
test.setSomething1(0);  //could, but probably won't throw Exception
test.setSomething2(0);  //could, but probably won't throw Exception

I would like to execute: test.setSomething2(0); even if test.setSomething(0) (the line above it) throws an exception. Is there a way to do this OTHER than:

try{
   test.setSomething1(0);
}catch(Exception e){
   //ignore
}
try{
   test.setSomething2(0);
}catch(Exception e){
   //ignore
}

I have a lot of test.setSomething’s in a row and all of them could throw Exceptions. If they do, I just want to skip that line and move to the next one.

For clarification, I don’t care if it throws an Exception, and I can’t edit the source code of the code which throws this exception.

THIS IS A CASE WHERE I DON’T CARE ABOUT THE EXCEPTIONS (please don’t use universally quantified statements like «you should never ignore Exceptions»). I am setting the values of some Object. When I present the values to a user, I do null checks anyway, so it doesn’t actually matter if any of the lines of code execute.

asked Feb 22, 2015 at 15:15

Nick's user avatar

NickNick

1,7536 gold badges23 silver badges38 bronze badges

7

try {
 // Your code...
} catch (Exception ignore) { }

Use the word ignore after the Exception keyword.

answered Sep 15, 2016 at 19:17

Joe Almore's user avatar

Joe AlmoreJoe Almore

4,0759 gold badges53 silver badges77 bronze badges

4

There is no way to fundamentally ignore a thrown exception. The best that you can do is minimize the boilerplate you need to wrap the exception-throwing code in.

If you are on Java 8, you can use this:

public static void ignoringExc(RunnableExc r) {
  try { r.run(); } catch (Exception e) { }
}

@FunctionalInterface public interface RunnableExc { void run() throws Exception; }

Then, and implying static imports, your code becomes

ignoringExc(() -> test.setSomething1(0));
ignoringExc(() -> test.setSomething2(0));

answered Feb 22, 2015 at 15:26

Marko Topolnik's user avatar

Marko TopolnikMarko Topolnik

196k29 gold badges320 silver badges437 bronze badges

4

IntelliJ Idea IDE suggests to rename a variable to ignored

when it isn’t used.

This is my sample code.

try {
    messageText = rs.getString("msg");
    errorCode = rs.getInt("error_code");
} catch (SQLException ignored) { }

answered Jul 2, 2019 at 10:52

ivanoklid's user avatar

ivanoklidivanoklid

811 silver badge4 bronze badges

Unfortunately no, there isn’t, and this is by intention. When used correctly, exceptions should not be ignored as they indicate that something didn’t work and that you probably shouldn’t continue down your normal execution path. Completely ignoring exceptions is an example of the ‘Sweep it under the rug’ anti-pattern, which is why the language doesn’t support doing so easily.

Perhaps you should look at why TestClass.setSomething is throwing exceptions. Is whatever you’re trying to ‘test’ really going to be valid if a bunch of setter methods didn’t work correctly?

answered Feb 22, 2015 at 15:21

Dogs's user avatar

DogsDogs

2,9031 gold badge19 silver badges15 bronze badges

You can’t ignore exception in Java. If a method declares being able to throw something this is because something important can’t be done, and the error can’t be corrected by the method designer. So if you really wan’t to simplify your life encapsulate the method call in some other method like this :

class MyExceptionFreeClass {
  public static void setSomething1(TestClass t,int v) {
    try {
      t.setSomething1(v);
    } catch (Exception e) {}
  public static void setSomething2(TestClass t,int v) {
    try {
      t.setSomething2(v);
    } catch (Exception e) {}
}

and call it when you need it:

TestClass test=new TestClass();
MyExceptionFreeClass.setSomething1(test,0);
MyExceptionFreeClass.setSomething2(test,0);

answered Feb 22, 2015 at 15:25

Jean-Baptiste Yunès's user avatar

You should not ignore Exceptions. You should handle them. If you want to make your test code simple, then add the try-catch block into your functions. The greatest way to ignore exceptions is to prevent them by proper coding.

answered Feb 22, 2015 at 15:21

Lajos Arpad's user avatar

Lajos ArpadLajos Arpad

64.9k38 gold badges101 silver badges176 bronze badges

I know this is old, but I do think there are occasions when you want to ignore an exception. Consider you have a string that contains a delimited set of parts to be parsed. But, this string can sometimes contain say, 6 or 7 or 8 parts. I don’t feel that checking the len each time in order to establish an element exists in the array is as straight forward as simply catching the exception and going on. For example, I have a string delimited by ‘/’ character that I want to break apart:

public String processLine(String inLine) {
    partsArray = inLine.split("/");

    //For brevity, imagine lines here that initialize
    //String elems[0-7] = "";

    //Now, parts array may contains 6, 7, or 8 elements
    //But if less than 8, will throw the exception
    try {
        elem0 = partsArray[0];
        elem1 = partsArray[1];
        elem2 = partsArray[2];
        elem3 = partsArray[3];
        elem4 = partsArray[4];
        elem5 = partsArray[5];
        elem6 = partsArray[6];
        elem7 = partsArray[7];
    catch (ArrayIndexOutOfBoundsException ignored) { }

    //Just to complete the example, we'll append all the values
    //and any values that didn't have parts will still be
    //the value we initialized it to, in this case a space.
    sb.append(elem0).append(elem1).append(elem2)...append(elem7);

    //and return our string of 6, 7, or 8 parts
    //And YES, obviously, this is returning pretty much
    //the same string, minus the delimiter.
    //You would likely do things to those elem values
    //and then return the string in a more formatted way.
    //But was just to put out an example where
    //you really might want to ignore the exception
    return sb.toString();
}

answered Jul 31, 2019 at 14:59

user25839's user avatar

Those who write empty catch blocks shall burn in the Hell for the eternity.

Or worse, they will be forced to debug the damn rubbish they wrote forever and ever.

That said, one thing you might want to do is writing exception handling in a less verbose way. The NoException library is very good at that.

answered Nov 16, 2020 at 18:12

zakmck's user avatar

zakmckzakmck

2,7151 gold badge37 silver badges53 bronze badges

You can ignore exceptions as long as it makes sense.
In this case, there can be no repeated email accounts.

So, if findByEmail does not throw the exception, you throw the exception that really matters in the specific case

        try {

            this.findByEmail();

            throw new EmailAlreadyExistsException();

        } catch (AccountNotFoundException ignored) {
           
        } catch (InvalidAccountStatusException e) {
            throw e;
        }

        this.createAccount();

answered Sep 17 at 18:07

Roberto Messa's user avatar

I have the following code:

TestClass test=new TestClass();
test.setSomething1(0);  //could, but probably won't throw Exception
test.setSomething2(0);  //could, but probably won't throw Exception

I would like to execute: test.setSomething2(0); even if test.setSomething(0) (the line above it) throws an exception. Is there a way to do this OTHER than:

try{
   test.setSomething1(0);
}catch(Exception e){
   //ignore
}
try{
   test.setSomething2(0);
}catch(Exception e){
   //ignore
}

I have a lot of test.setSomething’s in a row and all of them could throw Exceptions. If they do, I just want to skip that line and move to the next one.

For clarification, I don’t care if it throws an Exception, and I can’t edit the source code of the code which throws this exception.

THIS IS A CASE WHERE I DON’T CARE ABOUT THE EXCEPTIONS (please don’t use universally quantified statements like «you should never ignore Exceptions»). I am setting the values of some Object. When I present the values to a user, I do null checks anyway, so it doesn’t actually matter if any of the lines of code execute.

asked Feb 22, 2015 at 15:15

Nick's user avatar

NickNick

1,7536 gold badges23 silver badges38 bronze badges

7

try {
 // Your code...
} catch (Exception ignore) { }

Use the word ignore after the Exception keyword.

answered Sep 15, 2016 at 19:17

Joe Almore's user avatar

Joe AlmoreJoe Almore

4,0759 gold badges53 silver badges77 bronze badges

4

There is no way to fundamentally ignore a thrown exception. The best that you can do is minimize the boilerplate you need to wrap the exception-throwing code in.

If you are on Java 8, you can use this:

public static void ignoringExc(RunnableExc r) {
  try { r.run(); } catch (Exception e) { }
}

@FunctionalInterface public interface RunnableExc { void run() throws Exception; }

Then, and implying static imports, your code becomes

ignoringExc(() -> test.setSomething1(0));
ignoringExc(() -> test.setSomething2(0));

answered Feb 22, 2015 at 15:26

Marko Topolnik's user avatar

Marko TopolnikMarko Topolnik

196k29 gold badges320 silver badges437 bronze badges

4

IntelliJ Idea IDE suggests to rename a variable to ignored

when it isn’t used.

This is my sample code.

try {
    messageText = rs.getString("msg");
    errorCode = rs.getInt("error_code");
} catch (SQLException ignored) { }

answered Jul 2, 2019 at 10:52

ivanoklid's user avatar

ivanoklidivanoklid

811 silver badge4 bronze badges

Unfortunately no, there isn’t, and this is by intention. When used correctly, exceptions should not be ignored as they indicate that something didn’t work and that you probably shouldn’t continue down your normal execution path. Completely ignoring exceptions is an example of the ‘Sweep it under the rug’ anti-pattern, which is why the language doesn’t support doing so easily.

Perhaps you should look at why TestClass.setSomething is throwing exceptions. Is whatever you’re trying to ‘test’ really going to be valid if a bunch of setter methods didn’t work correctly?

answered Feb 22, 2015 at 15:21

Dogs's user avatar

DogsDogs

2,9031 gold badge19 silver badges15 bronze badges

You can’t ignore exception in Java. If a method declares being able to throw something this is because something important can’t be done, and the error can’t be corrected by the method designer. So if you really wan’t to simplify your life encapsulate the method call in some other method like this :

class MyExceptionFreeClass {
  public static void setSomething1(TestClass t,int v) {
    try {
      t.setSomething1(v);
    } catch (Exception e) {}
  public static void setSomething2(TestClass t,int v) {
    try {
      t.setSomething2(v);
    } catch (Exception e) {}
}

and call it when you need it:

TestClass test=new TestClass();
MyExceptionFreeClass.setSomething1(test,0);
MyExceptionFreeClass.setSomething2(test,0);

answered Feb 22, 2015 at 15:25

Jean-Baptiste Yunès's user avatar

You should not ignore Exceptions. You should handle them. If you want to make your test code simple, then add the try-catch block into your functions. The greatest way to ignore exceptions is to prevent them by proper coding.

answered Feb 22, 2015 at 15:21

Lajos Arpad's user avatar

Lajos ArpadLajos Arpad

64.9k38 gold badges101 silver badges176 bronze badges

I know this is old, but I do think there are occasions when you want to ignore an exception. Consider you have a string that contains a delimited set of parts to be parsed. But, this string can sometimes contain say, 6 or 7 or 8 parts. I don’t feel that checking the len each time in order to establish an element exists in the array is as straight forward as simply catching the exception and going on. For example, I have a string delimited by ‘/’ character that I want to break apart:

public String processLine(String inLine) {
    partsArray = inLine.split("/");

    //For brevity, imagine lines here that initialize
    //String elems[0-7] = "";

    //Now, parts array may contains 6, 7, or 8 elements
    //But if less than 8, will throw the exception
    try {
        elem0 = partsArray[0];
        elem1 = partsArray[1];
        elem2 = partsArray[2];
        elem3 = partsArray[3];
        elem4 = partsArray[4];
        elem5 = partsArray[5];
        elem6 = partsArray[6];
        elem7 = partsArray[7];
    catch (ArrayIndexOutOfBoundsException ignored) { }

    //Just to complete the example, we'll append all the values
    //and any values that didn't have parts will still be
    //the value we initialized it to, in this case a space.
    sb.append(elem0).append(elem1).append(elem2)...append(elem7);

    //and return our string of 6, 7, or 8 parts
    //And YES, obviously, this is returning pretty much
    //the same string, minus the delimiter.
    //You would likely do things to those elem values
    //and then return the string in a more formatted way.
    //But was just to put out an example where
    //you really might want to ignore the exception
    return sb.toString();
}

answered Jul 31, 2019 at 14:59

user25839's user avatar

Those who write empty catch blocks shall burn in the Hell for the eternity.

Or worse, they will be forced to debug the damn rubbish they wrote forever and ever.

That said, one thing you might want to do is writing exception handling in a less verbose way. The NoException library is very good at that.

answered Nov 16, 2020 at 18:12

zakmck's user avatar

zakmckzakmck

2,7151 gold badge37 silver badges53 bronze badges

You can ignore exceptions as long as it makes sense.
In this case, there can be no repeated email accounts.

So, if findByEmail does not throw the exception, you throw the exception that really matters in the specific case

        try {

            this.findByEmail();

            throw new EmailAlreadyExistsException();

        } catch (AccountNotFoundException ignored) {
           
        } catch (InvalidAccountStatusException e) {
            throw e;
        }

        this.createAccount();

answered Sep 17 at 18:07

Roberto Messa's user avatar

In this article, I show how to ignore checked exceptions in Java. I will start by describing the rationale behind it and the common pattern to resolve this issue. Then I will present some libraries for that purpose.

Checked and Unchecked Exceptions

In Java, a method can force its caller to deal with the occurrence of potential exceptions. The caller can use the try/catch clause, where the try contains the actual code and catch contains the code to execute when the exception occurs.

Alternatively, the caller can pass on that burden to its „parent caller“. This can go upwards until the main method is reached. If the main method also passes on the exception, the application will crash when an exception happens.

In the case of an exception, there are many scenarios where the application cannot continue to run and needs to stop. There are no alternative paths. Unfortunately, that means Java forces us to write code for a situation where the application shouldn‘t run anymore. Quite useless!

An option is to minimise that boilerplate code. We can wrap the exception into a RuntimeException, which is an unchecked exception. This has the effect that, even though the application still crashes, we don’t have to provide any handling code.

By no means do we log the exception and let the application continue like nothing has happened. It is possible, but similar to opening Pandora‘s Box.

We call exceptions we have to write extra code for “checked exceptions”, and the other ones of type RuntimeException “unchecked exceptions”.

Checked and Unchecked Exceptions

Checked and Unchecked Exceptions

Why Checked Exceptions at all?

We can find lots of checked exceptions in third-party libraries and even in the Java Class Library itself. The reason is quite obvious. A library vendor cannot predict in which context the developer will use their code.

Logically, they don’t know if our application has alternative paths. So they leave the decision to us. Their responsibility is to „label“ methods that can potentially throw exceptions. Those labels give us the chance to implement counter-actions.

A good example is the connection to a database. The library vendor marks the connection retrieval method with an exception. If we use the database as a cache, we can send our queries directly to our primary database. This is the alternative path.

If our database is not the cache, there is no way the application can continue to run. And it’s OK if the application crashes:

A lost database connection

Let’s put our theoretical example to real code:

public DbConnection getDbConnection(String username, String password) {
  try {
    return new DbProvider().getConnection(username, password);
  } catch (DbConnectionException dce) {
    throw new RuntimeException(dce);
  }
}

The database is not used as cache. In the event of a lost connection, we need to stop the application at once.

As described above, we wrap the DbConnectionException into a RuntimeException.

The required code is relatively verbose and always the same. This creates lots of duplication and decreases the readability.

The RuntimeException Wrapper

We can write a function to simplify this. It should wrap a RuntimeException over some code and return the value. We cannot simply pass code in Java. The function must be part of a class or interface. Something like this:

public interface RuntimeExceptionWrappable<T> {
  T execute() throws Exception;
}

public class RuntimeExceptionWrapper {
  public static <T> T wrap(RuntimeExceptionWrappable<T> runtimeExceptionWrappable) {
    try {
      return runtimeExceptionWrappable.execute();
    } catch (Exception exception) {
      throw new RuntimeException(exception);
    }
  }
}

public class DbConnectionRetrieverJava7 {
  public DbConnection getDbConnection(final String username, final String password) {
    RuntimeExceptionWrappable<DbConnection> wrappable = new RuntimeExceptionWrappable<DbConnection>() {
      public DbConnection execute() throws Exception {
        return new DbProvider().getConnection(username, password);
      }
    };
    return RuntimeExceptionWrapper.wrap(wrappable);
  }
}

The RuntimeException wrapping has been extracted into its own class. In terms of software design this might be the more elegant solution. Still, given the amount of code, we hardly can say the situation got better.

With Java 8 lambdas, things got easier. If we have an interface with one method only, then we just write the specific code of that method. The compiler does the rest for us. The unnecessary or „syntactic sugar code“ to create a specific or anonymous class is not required any more. That’s the basic use case for lambdas.

In Java 8, our example above looks like:

@FunctionalInterface
public interface RuntimeExceptionWrappable<T> {
  T execute() throws Exception;
}

public class DbConnectionRetrieverJava8 {
  public DbConnection getDbConnection(String username, String password) {
    return RuntimeExceptionWrapper.wrap(() ->
      new DbProvider().getConnection(username, password));
  }
}

The difference is quite obvious. The code is more concise.

Exceptions in Streams & Co.

RuntimeExceptionWrappable is a very generic interface. It is just a function that returns a value. Use cases for that function, or its variations, appear all over. For our convenience, Java‘s Class Library has a set of such common Interfaces built-in. They are in the package java.util.function and are better known as the „Functional Interfaces“. Our RuntimeExceptionWrappable is similar to java.util.function.Supplier<T>.

These interfaces form the prerequisite of the powerful Stream, Optional and other features which are also part of Java 8. In particular, Stream comes with a lot of different methods for processing collections. Many of these methods have a «Functional Interface» as parameter.

Let’s quickly switch the use case. We have a list of URL strings that we want to map into a list of objects of type java.net.URL.

The following code does not compile:

public List<URL> getURLs() {
  return Stream
    .of("https://www.hahnekamp.com", "https://www.austria.info")
    .map(this::createURL)
    .collect(Collectors.toList());
}

private URL createURL(String url) throws MalformedURLException {
  return new URL(url);
}

There is a big problem when it comes to exceptions. The Interfaces defined in java.util.function don‘t throw exceptions. That’s why our method createURL doesn’t have the same signature as java.util.funcion.Function, which is the parameter of the map method.

What we can do, is to write the try/catch block inside the lambda:

public List<URL> getURLs() {
  return Stream
    .of("https://www.hahnekamp.com", "https://www.austria.info")
    .map(url -> {
      try {
        return this.createURL(url);
      } catch (MalformedURLException e) {
        throw new RuntimeException(e);
      }
    })
    .collect(Collectors.toList());
}

This compiles, but doesn‘t look nice either. We can now take a step further and write a wrapper function along a new interface similar to RuntimeExceptionWrappable:

@FunctionalInterface
public interface RuntimeWrappableFunction<T, R> {
 R apply(T t) throws Exception;
}

public class RuntimeWrappableFunctionMapper {
 public static <T, R> Function<T, R> wrap(
   RuntimeWrappableFunction<T, R> wrappable) {
   return t -> {
     try {
       return wrappable.apply(t);
     } catch(Exception exception) {
       throw new RuntimeException(exception);
     }
   };
  }
}

And apply it to our Stream example:

public List<URL> getURLs() {
  return Stream
    .of("https://www.hahnekamp.com", "https://www.austria.info")
    .map(RuntimeWrappableFunctionMapper.wrap(this::createURL))
    .collect(Collectors.toList());
}

private URL createURL(String url) throws MalformedURLException {
  return new URL(url);
}

Great! Now we have a solution, where we can:

  • run code without catching checked exceptions,
  • use exception-throwing lambdas in Stream, Optional, etc.

SneakyThrow to Help

The SneakyThrow library lets you skip copying and pasting the code snippets from above. Full disclosure: I am the author.

SneakyThrow comes with two static methods. One runs code without catching checked exceptions. The other method wraps an exception-throwing lambda into one of the Functional Interfaces:

//SneakyThrow returning a result
public DbConnection getDbConnection(String username, String password) {
  return sneak(() -> new DbProvider().getConnection(username, password));
}

//SneakyThrow wrapping a function
public List<URL> getURLs() {
  return Stream
   .of("https://www.hahnekamp.com", "https://www.austria.info")
   .map(sneaked(this::createURL))
   .collect(Collectors.toList());
}

Alternative Libraries

ThrowingFunction

//ThrowingFunction returning a result
public DbConnection getDbConnection(String username, String password) {
  return unchecked(() -> 
       new DbProvider().getConnection(username, password))
    .get();
}

//ThrowingFunction returning a function
public List<URL> getURLs() {
  return Stream
    .of("https://www.hahnekamp.com", "https://www.austria.info")
    .map(unchecked(this::createURL))
    .collect(Collectors.toList());
}

In contrast to SneakyThrow, ThrowingFunction can’t execute code directly. Instead, we have to wrap it into a Supplier and call the Supplier afterwards. This approach can be more verbose than SneakyThrow.

If you have multiple unchecked Functional Interfaces in one class, then you have to write the full class name with each static method. This is because unchecked does not work with method overloading.

On the other hand, ThrowingFunction provides you with more features than SneakyThrow. You can define a specific exception you want to wrap. It is also possible that your function returns an Optional, aka “lifting”.

I designed SneakyThrow as an opinionated wrapper of ThrowingFunction.

Vavr

Vavr, aka JavaSlang, is another alternative. In contrast to SneakyThrow and ThrowingFunction it provides a complete battery of useful features that enhance Java’s functionality.

For example, it comes with pattern matching, tuples, an own Stream and much more. If you haven’t heard of it, it is definitely worth a look. Prepare to invest some time in order to understand its full potential.

//Vavr returning a result
public DbConnection getDbConnection(String username, String password) {
  return Try.of(() -> 
    new DbProvider().getConnection(username, password))
    .get();
}

//Vavr returning a function
public List<URL> getURLs() {
  return Stream
    .of("https://www.hahnekamp.com", "https://www.austria.info")
    .map(url -> Try.of(() -> this.createURL(url)).get())
    .collect(Collectors.toList());
}

Project Lombok

Such a list of libraries is not complete without mentioning Lombok. Like Vavr, it offers much more functionality than just wrapping checked exceptions. It is a code generator for boilerplate code and creates full Java Beans, Builder objects, logger instances and much more.

Lombok achieves its goals by bytecode manipulation. Therefore, we require an additional plugin in our IDE.

@SneakyThrows is Lombok’s annotation for manipulating a function with a checked exception into one that doesn’t. This approach doesn’t depend on the usage of lambdas, so you can use it for all cases. It is the least verbose library.

Please keep in mind that Lombok manipulates the bytecode which can cause problems with other tooling you might use.

//Lombok returning a result
@SneakyThrows
public DbConnection getDbConnection(String username, String password) {
  return new DbProvider().getConnection(username, password);
}

//Lombok returning a function
public List<URL> getURLs() {
  return Stream
    .of("https://www.hahnekamp.com", "https://www.austria.info")
    .map(this::createURL)
    .collect(Collectors.toList());
}

@SneakyThrows
private URL createURL(String url) {
  return new URL(url);
}

Further Reading

The code is available on GitHub.

  • https://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html
  • https://www.artima.com/intv/handcuffs.html
  • http://www.informit.com/articles/article.aspx?p=2171751&seqNum=3
  • https://github.com/rainerhahnekamp/sneakythrow
  • https://projectlombok.org/features/SneakyThrows
  • https://github.com/pivovarit/ThrowingFunction
  • https://github.com/vavr-io/vavr
  • http://www.baeldung.com/java-lambda-exceptions

Sometimes, you may want to ignore an exception thrown by your Java program without stopping the program execution.

To ignore an exception in Java, you need to add the try...catch block to the code that can throw an exception, but you don’t need to write anything inside the catch block.

Let’s see an example of how to do this.

Suppose you have a checkAge() method that checks whether the age variable in your code is greater than 18 as follows:

static void checkAge(int age) throws Exception {
    if (age < 18) {
        throw new Exception( "Age must be greater than 18" );
    }
}

In your main() method, you can surround the call to the checkAge() method with a try...catch block.

The catch block parameter should be named as ignored to let Java know that this exception is ignored:

public static void main(String[] args) {
    try {
        checkAge(15);
    } catch (Exception ignored) { }

    System.out.println("Ignoring the exception");
    System.out.println("Continue code as normal");
}

When the exception happens and the catch block above is executed, nothing will be done by Java.

The exception is ignored and the next line of code below the catch block will be executed as if nothing has happened.

The output:

Ignoring the exception
Continue code as normal

Process finished with exit code 0

When you have multiple exceptions to ignore, you need to put the try...catch block in each of the exceptions as shown below:

try {
    checkAge(12);
} catch (Exception ignored) { }

try {
    checkAge(15);
} catch (Exception ignored) { }

try {
    checkAge(16);
} catch (Exception ignored) { }

The code above gets redundant pretty fast. You can optimize the code by creating a wrapper method that has the try...catch block ready for your runnable function.

You need to create a functional interface that serves as the type of the method you want to ignore.

Consider the ignoreExc() function below:

static void ignoreExc(Runnable r) {
    try {
        r.run();
    } catch (Exception ignored) { }
}

@FunctionalInterface
interface Runnable {
    void run() throws Exception;
}

The call to run() method inside the ignoreExc() function will execute the Runnable you passed into the method.

Finally, you only need to use the ignoreExc() function to call your actual method with a lambda expression as follows:

public static void main(String[] args) {

    ignoreExc(() -> checkAge(16));
    ignoreExc(() -> checkAge(17));
    ignoreExc(() -> checkAge(18));

    System.out.println("Ignoring the exception");
    System.out.println("Continue code as normal");
}

The checkAge() method exceptions will be ignored because there’s nothing in the catch block of the ignoreExc() function.

With the ignoreExc() function, you’ve reduced the need to wrap your code with the try...catch block each time you want to ignore an exception.

Here’s the full code for ignoring exceptions in Java:

class Main {
    public static void main(String[] args) {

        ignoreExc(() -> checkAge(16));
        ignoreExc(() -> checkAge(17));
        ignoreExc(() -> checkAge(18));

        System.out.println("Ignoring the exception");
        System.out.println("Continue code as normal");
    }

    static void checkAge(int age) throws Exception {
        if (age < 18) {
            throw new Exception("Age must be greater than 18");
        }
    }

    static void ignoreExc(Runnable r) {
        try {
            r.run();
        } catch (Exception ignored) { }
    }

    @FunctionalInterface
    interface Runnable {
        void run() throws Exception;
    }
}

Now you’ve learned how to ignore exceptions thrown by a Java program.

Feel free to use the code in this tutorial for your project. 👍

Why you should ignore exceptions in Java and how to do it correctly

by Rainer Hahnekamp

KdtW2UtWR90oD8Q54rzNyTfQN24IafD1XJVQ

Photo by christoph wesi on Unsplash

In this article, I will show how to ignore checked exceptions in Java. I will start by describing the rationale behind it and the common pattern to resolve this issue. Then I will present some libraries for that purpose.

Checked and Unchecked Exceptions

In Java, a method can force its caller to deal with the occurrence of potential exceptions. The caller can use the try/catch clause, where the try contains the actual code and catch contains the code to execute when the exception occurs.

Alternatively, the caller can pass on that burden to its parent caller. This can go upwards until the main method is reached. If the main method also passes on the exception, the application will crash when an exception happens.

In the case of an exception, there are many scenarios where the application cannot continue to run and needs to stop. There are no alternative paths. Unfortunately, that means Java forces us to write code for a situation where the application shouldn’t run anymore. Quite useless!

An option is to minimise that boilerplate code. We can wrap the exception into a RuntimeException, which is an unchecked exception. This has the effect that, even though the application still crashes, we don’t have to provide any handling code.

By no means do we log the exception and let the application continue like nothing has happened. It is possible, but is similar to opening Pandora’s Box.

We call these exceptions, for which we have to write extra code, checked exceptions. The others of the RuntimeException type we call unchecked exceptions.

Dgx2RgjqtCmRsIuyoTzcBVKr7BwUO4EnT1KK

Checked and Unchecked Exceptions

Why Checked Exceptions at all?

We can find lots of checked exceptions in third-party libraries, and even in the Java Class Library itself. The reason is pretty straightforward. A library vendor cannot predict in which context the developer will use their code.

Logically, they don’t know if our application has alternative paths. So they leave the decision to us. Their responsibility is to “label” methods that can potentially throw exceptions. Those labels give us the chance to implement counter-actions.

A good example is the connection to a database. The library vendor marks the connection retrieval method with an exception. If we use the database as a cache, we can send our queries directly to our primary database. This is the alternative path.

If our database is not the cache, there is no way the application can continue to run. And it’s OK if the application crashes:

LJlE2Wwpgm0D17OoIMoEUTEgyaGbeKRCwuaA

https://imgflip.com/i/26h3xi

A lost database

Let’s put our theoretical example to real code:

public DbConnection getDbConnection(String username, String password) {  try {    return new DbProvider().getConnection(username, password);  } catch (DbConnectionException dce) {    throw new RuntimeException(dce);  }}

The database is not used as a cache. In the event of a lost connection, we need to stop the application at once.

As described above, we wrap the DbConnectionException into a RuntimeException.

The required code is relatively verbose and always the same. This creates lots of duplication and decreases the readability.

The RuntimeException Wrapper

We can write a function to simplify this. It should wrap a RuntimeException over some code and return the value. We cannot simply pass code in Java. The function must be part of a class or interface. Something like this:

public interface RuntimeExceptionWrappable<T> {  T execute() throws Exception;} public class RuntimeExceptionWrapper {  public static <T> T wrap(RuntimeExceptionWrappable<T> runtimeExceptionWrappable) {    try {      return runtimeExceptionWrappable.execute();    } catch (Exception exception) {      throw new RuntimeException(exception);    }  }} public class DbConnectionRetrieverJava7 {  public DbConnection getDbConnection(final String username, final String password) {    RuntimeExceptionWrappable<DbConnection> wrappable = new RuntimeExceptionWrappable<DbConnection>() {      public DbConnection execute() throws Exception {        return new DbProvider().getConnection(username, password);      }    };    return RuntimeExceptionWrapper.wrap(wrappable);  }}

The RuntimeException wrapping has been extracted into its own class. In terms of software design, this might be the more elegant solution. Still, given the amount of code, we can hardly say the situation got better.

With Java 8 lambdas, things got easier. If we have an interface with one method only, then we just write the specific code of that method. The compiler does the rest for us. The unnecessary or “syntactic sugar code” to create a specific or anonymous class is not required any more. That’s the basic use case for Lambdas.

In Java 8, our example above looks like:

@FunctionalInterfacepublic interface RuntimeExceptionWrappable<T> {  T execute() throws Exception;} public class DbConnectionRetrieverJava8 {  public DbConnection getDbConnection(String username, String password) {    return RuntimeExceptionWrapper.wrap(() ->      new DbProvider().getConnection(username, password));  }}

The difference is quite clear: the code is more concise.

Exceptions in Streams & Co.

RuntimeExceptionWrappable is a very generic interface. It is just a function that returns a value. Use cases for that function, or its variations, appear all over. For our convenience, Java’s Class Library has a set of such common Interfaces built-in. They are in the package java.util.function and are better known as the “Functional Interfaces.” Our RuntimeExceptionWrappable is similar to java.util.function.Supplier<;T>.

These interfaces form the prerequisite of the powerful Stream, Optional, and other features which are also part of Java 8. In particular, Stream comes with a lot of different methods for processing collections. Many of these methods have a “Functional Interface” as parameter.

Let’s quickly switch the use case. We have a list of URL strings that we want to map into a list of objects of type java.net.URL.

The following code does not compile:

public List<URL> getURLs() {  return Stream    .of(“https://www.hahnekamp.com", “https://www.austria.info")    .map(this::createURL)    .collect(Collectors.toList());} private URL createURL(String url) throws MalformedURLException {  return new URL(url);}

There is a big problem when it comes to exceptions. The Interfaces defined in java.util.function don’t throw exceptions. That’s why our method createURL doesn’t have the same signature as java.util.function.Function, which is the parameter of the map method.

What we can do is to write the try/catch block inside the lambda:

public List<URL> getURLs() {  return Stream    .of(“https://www.hahnekamp.com", “https://www.austria.info")    .map(url -> {      try {        return this.createURL(url);      } catch (MalformedURLException e) {        throw new RuntimeException(e);      }    })    .collect(Collectors.toList());}

This compiles, but doesn’t look nice either. We can now take a step further and write a wrapper function along a new interface similar to RuntimeExceptionWrappable`:

@FunctionalInterfacepublic interface RuntimeWrappableFunction<T, R> {  R apply(T t) throws Exception;} public class RuntimeWrappableFunctionMapper {  public static <T, R> Function<T, R> wrap(    RuntimeWrappableFunction<T, R> wrappable) {      return t -> {        try {          return wrappable.apply(t);        } catch(Exception exception) {          throw new RuntimeException(exception);        }      };    }}

And apply it to our Stream example:

public List<URL> getURLs() {  return Stream    .of(“https://www.hahnekamp.com”, “https://www.austria.info”)    .map(RuntimeWrappableFunctionMapper.wrap(this::createURL))    .collect(Collectors.toList());} private URL createURL(String url) throws MalformedURLException {  return new URL(url);}

Great! Now we have a solution, where we can:

  • run code without catching checked exceptions, and
  • use exception-throwing lambdas in Stream, Optional, and so on.

SneakyThrow to the rescue

The SneakyThrow library lets you skip copying and pasting the code snippets from above. Full disclosure: I am the author.

SneakyThrow comes with two static methods. One runs code without catching checked exceptions. The other method wraps an exception-throwing lambda into one of the Functional Interfaces:

//SneakyThrow returning a resultpublic DbConnection getDbConnection(String username, String password) {  return sneak(() -> new DbProvider().getConnection(username, password));} //SneakyThrow wrapping a functionpublic List<URL> getURLs() {  return Stream    .of(“https://www.hahnekamp.com", “https://www.austria.info")    .map(sneaked(this::createURL))    .collect(Collectors.toList());}

Alternative Libraries

ThrowingFunction

//ThrowingFunction returning a resultpublic DbConnection getDbConnection(String username, String password) {  return unchecked(() ->     new DbProvider().getConnection(username, password)).get();} //ThrowingFunction returning a functionpublic List<URL> getURLs() {  return Stream    .of(“https://www.hahnekamp.com", “https://www.austria.info")    .map(unchecked(this::createURL))    .collect(Collectors.toList());}

In contrast to SneakyThrow, ThrowingFunction can’t execute code directly. Instead, we have to wrap it into a Supplier and call the Supplier afterwards. This approach can be more verbose than SneakyThrow.

If you have multiple unchecked Functional Interfaces in one class, then you have to write the full class name with each static method. This is because unchecked does not work with method overloading.

On the other hand, ThrowingFunction provides you with more features than SneakyThrow. You can define a specific exception you want to wrap. It is also possible that your function returns an Optional, otherwise known as “lifting.”

I designed SneakyThrow as an opinionated wrapper of ThrowingFunction.

Vavr

Vavr, or “JavaSlang,” is another alternative. In contrast to SneakyThrow and ThrowingFunction, it provides a complete battery of useful features that enhance Java’s functionality.

For example, it comes with pattern matching, tuples, its own Stream and much more. If you haven’t heard of it, it is definitely worth a look. Prepare to invest some time in order to understand its full potential.

//Vavr returning a resultpublic DbConnection getDbConnection(String username, String password) {  return Try.of(() ->   new DbProvider().getConnection(username, password))    .get();} //Vavr returning a functionpublic List<URL> getURLs() {  return Stream    .of(“https://www.hahnekamp.com", “https://www.austria.info")    .map(url -> Try.of(() -> this.createURL(url)).get())    .collect(Collectors.toList());}

Project Lombok

Such a list of libraries is not complete without mentioning Lombok. Like Vavr, it offers much more functionality than just wrapping checked exceptions. It is a code generator for boilerplate code and creates full Java Beans, Builder objects, logger instances, and much more.

Lombok achieves its goals by bytecode manipulation. Therefore, we require an additional plugin in our IDE.

@SneakyThrows is Lombok’s annotation for manipulating a function with a checked exception into one that doesn’t. This approach doesn’t depend on the usage of lambdas, so you can use it for all cases. It is the least verbose library.

Please keep in mind that Lombok manipulates the bytecode which can cause problems with other tooling you might use.

//Lombok returning a result@SneakyThrowspublic DbConnection getDbConnection(String username, String password) {  return new DbProvider().getConnection(username, password);} //Lombok returning a functionpublic List<URL> getURLs() {  return Stream    .of(“https://www.hahnekamp.com", “https://www.austria.info")    .map(this::createURL)    .collect(Collectors.toList());} @SneakyThrowsprivate URL createURL(String url) {  return new URL(url);}

Further Reading

The code is available on GitHub

  • https://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html
  • https://www.artima.com/intv/handcuffs.html
  • http://www.informit.com/articles/article.aspx?p=2171751&seqNum=3
  • https://github.com/rainerhahnekamp/sneakythrow
  • https://projectlombok.org/features/SneakyThrows
  • https://github.com/pivovarit/ThrowingFunction
  • https://github.com/vavr-io/vavr
  • http://www.baeldung.com/java-lambda-exceptions

Originally published at www.rainerhahnekamp.com on March 17, 2018.


Learn to code for free. freeCodeCamp’s open source curriculum has helped more than 40,000 people get jobs as developers. Get started

Понравилась статья? Поделить с друзьями:
  • Java длинная ошибка
  • Java виды ошибок
  • Java деление на ноль какая ошибка
  • Java вызов ошибки
  • Java выдает ошибку 1603