Is There Any Valid Reason to Ever Ignore a Caught Exception

Is there any valid reason to ever ignore a caught exception

While there are some reasonable reasons for ignoring exceptions; however, generally it is only specific exceptions that you are able to safely ignore. As noted by Konrad Rudolph, you might have to catch and swallow an error as part of a framework; and as noted by osp70, there might be an exception generated by a framework that you know you can ignore.

In both of these cases though, you will likely know the exception type and if you know the type then you should have code similar to the following:

try {
// Do something that might generate an exception
} catch (System.InvalidCastException ex) {
// This exception is safe to ignore due to...
} catch (System.Exception ex) {
// Exception handling
}

In the case of your application, is sounds like something similar might apply in some cases; but the example you give of a database save returning an "OK" even when there is an exception is not a very good sign.

How to ignore Exceptions in Java

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));

Python: How to ignore an exception and proceed?

except Exception:
pass

Python docs for the pass statement

Is it okay that I sometimes sink my exceptions?

Yes, it is common, but in general it shouldn't be done.

There are exceptions like OutOfMemoryException which are better not caught, unless you catch them to attempt to terminate your application gracefully.

In the majority of cases, swallowing System.Exception or System.SystemException will inevitably hide further run-time problems.

Is it OK to ignore InterruptedException if nobody calls interrupt()?

Ignoring a checked exception is never considered to be safe.

It may seem okay for you at the moment, but if any other programmer uses your code/API, they should expect the standard behaviour:

  • Which is, the thread "reacting" to an interrupt call, but with whatever "reaction" the thread's documentation describes.

  • I mean it's up to the thread's developer to both decide and document exactly how a thread handles an interrupt, and Java has not any pre-defined rule, but you should document your thread's "reaction" (with Documentation comments).

  • For example, the InterruptedException is only thrown from blocking methods (like Thread.sleep(...)), but never from normal lines of code (meaning the interrupt is simply ignored by default), which allows developers to choose (and document) thread's reaction, like:

    • Maybe abort, by cancelling task(s) in mid of progress.

    Which takes time for development, if not already supported.

    • Maybe postpone (or soft-ignore), by calling Thread.currentThread().interrupt() in catch-block.

    Which simulates interrupt happening while normal code was running.

    • Maybe crash, by throwing a java.lang.Error (or sub-class), and passing InterruptedException-instance as cause.

    Which unless documented, is least desired or expected.

To explain postpone; An empty catch block is dangerous with InterruptedException, since the JVM removes the interrupted flag, and it should definitely be set again in the catch block, like:

try {
Thread.sleep(1000);
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
}

In my opinion, this is the minimum catch implementation for InterruptedExceptions. Checking for the isInterrupted flag in a loop doesn't hurt much, either.

It is little overhead compared to your future programmer self's hassle searching a day or two for unexpected thread behaviour as you project may have grown a bit.

If you feel that your code's readability suffers from those catch implementations, you may implement your own safeSleep utility method, which takes care of the Exceptions and sets the flag properly.

On the other hand, InterruptedException is not thrown by the JVM itself in case of a hardware failure, it is a user indicated Exception only. So, if you do not propagate your Threads reference, there won't be any other Threads that are able to call Thread.interrupt() on it. That's it technically. But you shouldn't underestimate the human factor and your programs evolution.

Edit: As ruakh pointed out, there actually is a way to get a Threads reference and thus to schedule an Thread.interrupt() call. That way the developer in heat may not even have to look at the class, that implements your uninterruptible Thread. In my opinion that's even another reason, to implement proper exception handling.

Another thing: If you're not throwing an Exception, logging such an event on a level beyond INFO may be a good choice.

When is it OK to catch NullPointerException?

Effective java recommend that we shouldn't catch NullPointerException. Is it always right?

In nearly all cases it is correct.

NullPointerException is usually a result of a bug; i.e. your application encountered a null object reference in a situation where it was not anticipated, and then attempted to use it. In this scenario, since you (the programmer) did not anticipate the null, it is next to impossible to know whether it is safe to attempt to recover, and / or to know what "remediation" might be required. So the best thing to do is to let the NPE propagate to the base level, and then treat it as a generic bug. (In "network service" applications, it may be appropriate to return a "service error" response, and attempt to continue.)

The other scenario is where you (the programmer) anticipate that a null might be delivered. In this case, the best strategy is (nearly always) to explicitly test for the null before you attempt to use it, thereby avoiding the NPE ... and the need to handle it. There are two reasons for this:

  • Exception handling is typically expensive. Indeed it can be many orders of magnitude more expensive than testing for a null.

  • If you allow the expected NPE to happen and then catch it, you are liable to also catch other unexpected NPEs ... and handle them incorrectly.


Note that I qualified the above by saying "nearly always". It is theoretically possible to have a scenario where explicit tests for null clutter up your code so much that it is at least worth considering allowing the NPE to happen. However, there is still the possibility of unexpected NPEs as well ... depending on the code. So this approach is always potentially fragile.

(FWIW - I've never encountered a real case where this would be a good idea ...)


In many cases of catching NullPointerException, catch body only calls printStackTrace().

That is probably bad code. Doing nothing is rarely the correct way to recover from an NPE.

If I don't catch NullPointerException and call printStackTrace(), how I can check the place where the exception occurred?

You let the NPE propagate to the base level. There you catch and print (or log) a stacktrace for all unhandled exceptions, and then either bail out or attempt to recover ... if that is feasible.

And also if I catch NullPointerException and the catch body is empty, we cannot get any stack information at that time, can we?

Never, ever do this! It is called "squashing" and is dangerous. (Especially since, as I explained above, the NPE may be due to something that you / your code did not anticipate.)

And no, if you do this, you can't get the stack trace. It is gone.


FOLLOWUP

I don't place much trust / faith on some general strategies for "avoiding NPEs"1. For instance stuff like this:

return (someObject != null) ? someObject.toString() : "";

always make me suspicious that the programmer is not thinking about the problem. Why was someObject a null in the first place?

A NPE is caused by having a null in place where you don't expect it. As such, NPEs are usually symptoms of a problem rather than the actual problem itself. To my mind, NPEs are not something to be avoided. Rather, you should be using the NPEs to find and fix the root cause of the unexpected null. Code like the above that avoids the NPE gets in the way of that goal.

So I prefer / recommend strategies for avoiding null values in unexpected places.

  • Make sure that every reference field is gets initialized to a non-null value ... unless null is a meaningful value.

  • Try to avoid having null as a meaningful value, especially if there is an alternative. For instance, an empty String, a zero length array, an empty collection, a distinguished instance that means "undefined" or whatever. Or, for Java 8 and later, use Optional.

  • Don't return null as an error or an indication of a special case. (Throw an exception or return a distinguished value.)

  • Check early for unanticipated null values (e.g. null arguments), and throw the NPE sooner rather than later.

  • In the few places where a null argument or result is legitimate, make sure that your javadocs document this clearly and explicitly. If there is no documentation, then the implication should be that null is not allowed and won't be returned.

And wherever you get an NPE, make sure that you find and fix the real source of the problem ... not just the specific statement that threw the exception.

1 - There is value in knowing about places in the standard Java APIs where null is used (or abused) as a return value. For instance, Class.getResourceAsStream(...) or HttpRequest.getParam(...). Those "advice for avoiding NPE" documents are useful in as much that they point out these traps.



Related Topics



Leave a reply



Submit