Is it possible to make an exception that is optional to be caught?
In other words, an exception that can either:
be caught in a try-catch block
or skipped if no try-catch block exists for it
To visualize, I have a ReportedException, which is just a plain subclass of RuntimeException, and want to be able to catch it when it's needed:
try
{
hideWindow();
}
catch (ReportedException ex)
{
// Window could not be hidden.
// Exception has already been caught and logged by parseInput(),
// and now we're going to do something more.
printAdditionalErrorMessage();
}
Note: I edited the above example to better fit my question.
or skip catching if the result is irrelevant:
hideWindow(); // We don't care if there was an error or not.
openAnotherWindow();
I know I can leave the catch block empty and have the same thing as above, but I use ReportedException very often and it would make my code highly unreadable.
If it's impossible (I suspect it is), what alternative/walkaround would you recommend?
P.S. The method names used in the examples are just foo's and bar's.
EDIT: I know I don't need to catch RuntimeExceptions. What I want is to ignore them if they occur.
Exceptions should be used for exceptional situations.
From your example, if the window not being hidden is a typical event, it shouldn't throw an exception. If that is your function, then use a return value to indicate whether it was successful instead of throwing an exception. Then you can safely ignore the return value when you don't care if it succeeded or not.
If you do not have control over that method, then you can wrap it in another method that catches the exception and turns it into a return value. E.g.
private boolean tryHideWindow() {
try {
hideWindow();
}
catch (ReportedException ex) {
return false;
}
return true;
}
If you need some parameters of the exception to determine what to do, then you could return the exception instead.
private static class MyReturnType {
private final Throwable thrown;
private final OrigRtnType returnVal;
public MyReturnType(Throwable thrown) {
this.thrown = thrown;
this.returnVal = null;
}
public MyReturnType(OrigRtnType returnVal) {
this.thrown = null;
this.returnVal = returnVal
}
public boolean wasExceptionThrown() {
return thrown != null;
}
}
private MyReturnType tryHideWindow() {
try {
OrigRtnType returnVal = hideWindow();
}
catch (ReportedException ex) {
return new MyReturnType(ex);
}
return new MyReturnType(returnVal);
}
This is an answer to your question, but it is not necessarily a good idea. As others will doubless comment, using exceptions for program flow is less than ideal.
I'm a little fuzzy on how to use ThreadLocal (and there are apt to be some other tupos), but something like this:
public class IgnorableException {
static class DontIgnoreCount {
int count;
}
// Thread local variable containing each thread's ID
private static final ThreadLocal<DontIgnoreCount> dontIgnoreCount =
new ThreadLocal<DontIgnoreCount>();
static void incrementDontIgnore() {
DontIgnoreCount counter = dontIgnoreCount.get();
if (counter == null) {
counter = new DontIgnoreCount();
dontIgnoreCount.set(counter);
}
counter.count++;
}
static void decrementDontIgnore() {
DontIgnoreCount counter = dontIgnoreCount.get();
// Must not be null here
counter.count--;
static bool shouldSignal() {
DontIgnoreCount counter = dontIgnoreCount.get();
return counter.count > 0;
}
}
To use, invoke DontIgnoreCount.incrementIgnoreCount() early in try range, and DontIgnoreCount.decrementIgnoreCount() late in finally range.
When signalling an exception that follows this protocol, only signal it if shouldSignal returns true.
void iWannaCatchException() {
try {
IgnornableException.incrementDontIgnore();
int x = someOptionallySignallingMethod();
}
catch (...) {
...
}
finally {
IgnorableException.decrementDontIgnore();
}
}
void iDontWannaCatchException() {
int x = someOptionallySignallingMethod();
}
int someOptionallySignallingMethod() {
if (somethingBad) {
if (IgnorableException.shouldSignal()) {
throw new BadException();
}
}
return 42;
}
Note that not shown above are any throws clauses you'd have to add to keep the compiler happy. This mechanism would not remove the need for those.
You could also inplement a delegate/observer scheme, replacing the simple counter with a stack of observer objects, and pass a message to the observer vs throwing the exception. But this, by itself (without coupled exceptions/try ranges) would not allow blowing away the stack to the appropriate recovery point.
It sounds like you want to use exceptions for flow control, rather than for reporting truly exceptional cases.
Using exceptions for flow control is typically frowned upon. The common approach is to return a success/failure indication as the return value of the function.
You can use something like this:
try{
hideWindow();
}catch (ReportedException ex){
// ingore
}catch (NullPointerException ex){
killWindow();
}finally {
//to do something more.
}
Related
Is there any difference between following two methods?
Which one is preferable and why?
Prg1:
public static boolean test() throws Exception {
try {
doSomething();
return true;
} catch (Exception e) {
throw new Exception("No!");
}
}
Prg2:
public static boolean test() throws Exception {
try {
doSomething();
} catch (Exception e) {
throw new Exception("No!");
}
return true;
}
Consider these cases where you're not returning a constant expression:
Case 1:
public static Val test() throws Exception {
try {
return doSomething();
} catch (Exception e) {
throw new Exception("No!");
}
// Unreachable code goes here
}
Case 2:
public static Val test() throws Exception {
Val toReturn = null;
try {
toReturn = doSomething();
} catch (Exception e) {
throw new Exception("No!");
}
return toReturn;
}
I would prefer the first one. The second is more verbose and might cause some confusion when debugging.
If test() incorrectly returns null, and you see toReturn being initialized to null, you might think the problem is in test() (especially when test() is not just a simple example like this).
Even though it can only return null if doSomething returns null. But that might be hard to see at a glance.
You could then argue that, for consistency's sake, it's better to always use the first form.
Nope there is no difference between both the methods.
It will return true value in both the cases effectively by resuming the flow of the program as soon an and exception is handled.
Catch will be accessed only when an exception occurs.
I'm assuming this is a general question. Otherwise I might comment on other aspects of your method(s).
I think in the case or small methods like these it doesn't really matter. The method is short enough to understand immediately what's going on, what's related to what etc.
However, in the case of longer methods the flow is much easier to follow in the first example. In my opinion. It keeps together related code and related scenarios. When you're reading the method, the normal execution flow is not broken by the catch block, making it more obvious and "fluent".
public static boolean test() throws Exception {
try {
doSomething();
return true;
} catch (Exception e) {
throw new Exception("No!");
}
}
But I won't generalize this for all methods; it's all about the context.
There is no difference, but the first Prg1 is faster than the Prg2.
I need to test a constructor which throws an exception using JUnit.
Below is the constructor:
public EISThirdPartyClient(ClientConfiguration _config, String _serviceURL)
throws EISClientException {
super(_config, _serviceURL);
try {
ObjectMapperHolder.initialize(_config);
} catch (Exception e) {
throw new EISClientException(e);
}
}
Below is the test case:
#Test
public void testEISThirdPartyClientConctructor() throws EISClientException {
#SuppressWarnings("unused")
EISThirdPartyClient client = new EISThirdPartyClient(new ClientConfiguration(), "url");
boolean caughtException = false;
try {
ObjectMapperHolder.initialize(null);
} catch (Exception ex) {
if (ex instanceof EISClientException) {
caughtException = true;
assertTrue(ex.getCause() instanceof EISClientException);
} else {
ex.printStackTrace();
fail("Uncaught exception");
}
}
assertTrue(caughtException);
}
I am getting java.lang.AssertionError, which isn't what I'm expecting. Can someone tell me what I am doing wrong?
You're testing the wrong thing - you want to ensure that the construction of your object fails, not that it bails out when ObjectMapperHolder bails out.
You can also greatly simplify the test - you can expect that EISClientException is thrown without needing to do any further validation of the exception.
The main point is to get the test to fail with the minimum required amount of work. It seems that passing null as your configuration might do it, so here's an example with that:
#Test(expected = EISClientException.class)
public void testEISThirdPartyClientConctructor() throws EISClientException {
new EISThirdPartyClient(null, "url");
}
If this doesn't quite suit your needs, you may want to look into a mocking framework like Mockito to provide behavior when you are in the critical section of your code.
I want to continue with the next line from which error generated,
try{
statement A;
statement B;
statement C;
}
catch(NullPointerException NPE){.....}
Now assume that my statement A throws exception so I want to skip that and continue with B. Don't give my suggestion to put in catch/finally block or any other solution. I just want to know is this possible to skip and continue with next statement?
Yes, it is possible without the finally block.
try{
statement A;
}
catch(NullPointerException NPE){.....}
try{
statement B;
}
catch(NullPointerException NPE){.....}
try{
statement C;
}
catch(NullPointerException NPE){.....}
On the side note, I don't really think this is nice. If you managed to come to the point where you need this kind of flow control, you need to take a step back and rethink your code design.
It is not possible to execute statement B if A throws exception. One way is seperately try/catch block and other way is put other lines into finally block.
If your statements are similar and can be paramerized, use a loop:
for (int i = 0; i < statementCount; i++) {
try {
/** do what you need */
} catch(Exception e) {
}
}
or put it in separate method if it needs more parameters:
public static void main(String[] args) {
for (int i = 0; i < statementCount; i++) {
}
execute(params);
}
public void execute(Object... objects) {
try {
doSomthing(objects[0], objects[1]);
} catch(Exception e) {
}
}
If statements are abolutely different, Java 8 provides interesting solutions: method references and lambdas. So you can play arround with somthing like this:
public static void main(String[] args) {
execute(someObject, YourClass::method);
}
public void execute(Object param, Function<Object, Void> function) {
try {
function.apply(param);
} catch(Exception e) {
}
}
Like darijan already mentioned you could put every single statement into an own try-catch. Or if you know what may cause the exception you can simply check it befor you execute your statements
try{
if(parameterForStatementA != null) {
statementA;
}
if(parameterForStatementB != null) {
statementB;
}
if(parameterForStatementC != null) {
statementC;
}
} catch(Exception e) {
// something unexpected happened
}
Verifying parameters is usually more efficient than catching thrown exceptions
I am new to java, and to make clear of "System.out", i read relevant java source code, then find something i cannot understand.
First the source code of "System.out":
public final static PrintStream out = nullPrintStream();
then i went to nullPrintStream
private static PrintStream nullPrintStream() throws NullPointerException {
if (currentTimeMillis() > 0) {
return null;
}
throw new NullPointerException();
}
My question is: the program may throw a NullPointerException in the function nullPrintStream(), and we needn't to catch the exception in public final static PrintStream out = nullPrintStream();? To make clear of it, i wrote some test codes in Eclipse as follows:
package MainPackage;
public class Src {
private static int throwException() throws Exception{
int m = 1;
if(m == 0) {
throw new Exception();
}
return 0;
}
public static final int aTestObject = throwException(); <==Here i got an error
public static void main(String args[]) {
}
}
Just like i think, i got an error Unhandled exception type Exception, but why System.out is OK without doing with the NullPointerException?
Java has a special class of Exceptions called RuntimeExceptions. They all extend the RuntimeException object, which in turn extends the Exception object. The special thing about a RuntimeException (as opposed to a regular exception) is that it does not need to be explicitly thrown. Several different exceptions fit into this category, such as IllegalArgumentException, IllegalStateException etc...
The advantage of using RTE when you are coding is that you do not need to cover your code with a lot of try/catch/throws statements, especially if the exceptions are expected to be extremely rare and unlikely. Additionally, if you have a general mechanism in place for catching RTE, this will also help make sure your app deals with expection conditions cleanly.
That being said, RTEs can be much more difficult to deal with, as it is not obvious from the signature that a particular class or method will throw that type of exception. Consequently, they are not always a good idea for APIs, unless they are well documented.
A NullPointerException is a RuntimeException, and consequently, does not need to be explicitly declared in the method signature.
NullPointerException is a RuntimeException - it doesn't need to be explicitly caught.
if you make your method do this, it won't bomb on compile:
private static int throwException() throws Exception{
int m = 1;
if(m == 0) {
throw new RuntimeException();
}
return 0;
}
if i adhere to throw Exception() in private static int throwException() , how should i modify public static final int aTestObject = throwException();
You can need to intialise the value in a static block and catch the exception there.
public static final int aTestObject;
static {
try {
aTestObject = throwException(); <==Here i got an error
} catch (Exception e) {
throw new AssertionError(e);
}
}
I want to make the result variable final, how do I structure this code so that this compiles cleanly? I know I have done this in the past, but I can't remember how I structured it to make it work.
The following code is a straw man example, the code I am trying to clean up is much more complicated, this is just distilling the essence of what I am trying to accomplish.
private boolean someMethod()
{
final boolean result;
try
{
// do the logic here that might throw the following
// exceptions
}
catch (final IOException ioe)
{
result = false;
}
catch (final ClassNotFoundException cnfe)
{
result = false;
}
return result;
}
I can't put the result = true in the try block because it won't compile with both the catch blocks complaining that the final variable might already be assigned.
I can't put it in a finally block because that would generate the same complaints as in the try block?
I want to be able to set result = once and only once.
So where do you set result = true; to get it to compile cleanly?
It's a lot simpler to not set a variable.
private boolean someMethod() {
try {
// do the logic here that might throw the following
return true;
} catch (IOException ioe) {
// handle IOE
} catch (ClassNotFoundException cnfe) {
// handle CNFE
}
return false;
}
Trying to use final to enforce "assign exactly once" is always tricky. You can use a second variable:
private boolean someMethod()
{
boolean res;
try
{
// do the logic here that might throw the following
// exceptions
}
catch (final IOException ioe)
{
res = false;
}
catch (final ClassNotFoundException cnfe)
{
res = false;
}
final boolean result = res;
return result;
}
But the real question is, why not just remove the final qualifier?
You cannot reassign a value to a final variable, so this is impossible.
edit: It's also a contradiction to want to declare a variable that is local to a method as final and also change the value in the same method - why is it necessary to declare it as final at all in this method?
If you declare a local variable as final within a method then the value of that variable cannot be changed within the method.
Remove the final from the declaration of result, or get rid of the result local variable altogether and return directly from within the catch blocks and the end of the method.