Let's say I have method a() and method b() which both may throw an exception. In my program, there is a situation where I have to call at least one of them; it doesn't matter which I call. However, if one of them throws an exception, I have to call the other one. If they both throw an exception, I don't have to do anything.
I was thinking of doing something like this:
try {
a();
catch (Exception e) {
try {
b();
catch (Exception e) {
}
}
but I thought this would be impractical if I had more than two methods to call. So I was wondering if there were a more elegant or better way to do something I'm trying to do.
you can
abc:
{
try
{
a();
break abc;
}
catch(Exception e){}
try
{
b();
break abc;
}
catch(Exception e){}
try
{
c();
break abc;
}
catch(Exception e){}
}
if the chain is even longer, probably better
for(int i=0; i<4; i++)
{
try
{
switch(i)
{
case 0: a(); break;
case 1: b(); break;
case 2: c(); break;
case 3: d(); break;
}
}
catch(Exception e){} // next
}
You can return after each case, such that after the first success, a return is hit.
public void uponSuccessStop() {
try {
a();
return;
} catch (Exception e) {}
try {
b();
return;
} catch (Exception e) {}
try {
c();
return;
} catch (Exception e) {}
}
Another option would be to throw out exceptions, and use short-circuit boolean logic:
public boolean tryA() {
try {
a();
return true;
} catch (Exception e) {
return false;
}
}
// repeat for B and C
public void uponSuccessStop() {
boolean succeeded = tryA() || tryB() || tryC();
}
It is difficult to discuss practical options at such a level of generality, but you could do something like this:
boolean succeeded = false;
try {
a();
succeeded = true;
} catch (Exception e) {
// intentional ...
}
if (not succeeded) {
try {
b();
catch (Exception e) {
...
}
}
... and all sort of other arrangements where you use conditionals (or break or return) to avoid the nesting.
But whether they are more "elegant" ... or more readable ... will be highly context dependent. And also dependent on the reader. (As an experienced Java programmer, I have no difficulty understanding nested exceptions. In my experience, artificial constructions that are intended to avoid nesting can result in code that is harder to read / understand.)
I hope that you are not really going to catch Exception ... 'cos if you are, that is a much worse problem than than nesting of try / catch!!
Related
I've a custom exception with few attributes that inherits from Exception class.
Depending on instance of Exception I would like to return a code.
Code:
public int manageException(Exception exception) {
int code = 0;
if (exception instanceof MyCustomException) {
code = ((MyCustomException) exception).getCode();
} else if (exception instanceof NestedRuntimeException) {
code = 444;
} else if (exception instanceof HibernateException) {
code = 555;
} else {
code = 666;
}
return code;
}
If
You need to handle these exceptions in multiple locations, and
You don't want multiple catch blocks (one for each exception type) in each location
...then instanceof is about as clean as you're likely to get in Java 7.
Having said that, though, you could do this:
public void manageException(Runnable r) {
try {
r.run();
}
catch (NestedRuntimeException nre) {
throw new MyCustomException(444, nre);
}
catch (HibernateException he) {
throw new MyCustomException(555, he);
}
catch (Exception e) {
throw new MyCustomException(666, e);
}
}
...and then everywhere you need it:
try {
this.manageException(new Runnable() {
#Override
public void run() {
// Do something
}
});
}
catch (MyCustomException mce) {
int code = mce.getCode();
}
...but it's not buying you much and it's really ugly. :-)
In Java 8, it's a lot cleaner. manageException is the same, but the calls are just:
try {
this.manageException(() => {
// Do something here
});
}
catch (MyCustomException mce) {
int code = mce.getCode();
}
For me, the Java 8 version nearly starts winning over instanceof. The Java 7 version, not so much.
(Why Runnable in the above? Because the JDK authors decided not to define a new standard functional interface that accepts no arguments and has no return value; more in this question. They generalized the concept of Runnable instead. If the semantics bother you (they would me), you can define your own.)
You can use overloading like this:
public int manageException(MyCustomException e) {
return e.getCode();
}
public int manageException(NestedRuntimeException e) {
return 444;
}
public int manageException(HibernateExceptionexception e) {
return 555;
}
public int manageException(Exception e) {
return 666;
}
Edit after comment from #T.J. Crowder:
Keep in mind that you will still need multiple catch blocks in order to call the correct method. The overload is based on the compile-time type of the exception. Simply doing catch (Exception e) { int code = this.manageException(ex); } will always return 666.
If you want to map the type of exception to different error codes, you could use a map:
Map<Class<? extends Exception>, Integer> map = new HashMap<> ();
map.put (Exception.class, 5);
map.put (NullPointerException.class, 42);
try {
throw null; //throws NPE
} catch (Exception e) {
System.out.println (map.get (e.getClass ())); //output is 42
}
I think this would be easy expendable, as you could read the mapping from a config file instead of hard coding it, so you could add other exception and error codes without making changes to your code.
You have to test the return value of map.get() for null, as it could be an Exception you didn't specify before so there is no Integer mapped to it.
Attention: As mentioned in the first comment, this would only work if you want to have an exact mapping of Classes to error codes. If Subclasses of an exception should have the same error code as their super class, this solution won't work without modification.
I seem to be stuck with a very simple task that would require GOTO statements and, in my opinion, would justify a use of those.
I have the very simple task to exit a void on different conditions. Within its code, several dozen operations are being done and most of them can fail. I test them with try {}.
Now, based on the criticality of the operation, I either need to exit immediately and do nothing else, or, I just need to interrupt control flow and jump to a final point to do some cleaning up and then exit the method.
MWE:
public void myMethod () {
try { op1(); } catch (Exception e) { return; } // Fail here: exit immediately
try { op2(); } catch (Exception e) { cleanUpFirst(); return; } // Fail here: do Cleaning up first, then exit
try { op3(); } catch (Exception e) { return; } // Fail here: exit immediately
try { op4(); } catch (Exception e) { cleanUpFirst(); return; } // Fail here: do Cleaning up first, then exit
try { op5(); } catch (Exception e) { cleanUpFirst(); return; } // Fail here: do Cleaning up first, then exit
// ....
}
public void cleanUpFirst() { /* do something to clean up */ }
For code readability, I'd like to a) avoid a separate function and b) do not have more than one statement within the catch block; it just blows up the code. So, in my opinion this would perfectly justify the use of a GOTO statement.
However, the only solution I came up with, given that only two outcomes are possible, is this:
public void myMethod () {
do {
try { op1(); } catch (Exception e) { return; }
try { op2(); } catch (Exception e) { break; }
try { op3(); } catch (Exception e) { return; }
try { op4(); } catch (Exception e) { break; }
try { op5(); } catch (Exception e) { break; }
// ....
} while (1==0);
/* do domething to clean up */
}
Yes, I have heard of exceptions and that is is the Java way. Is that not as overkilled as using the separate void? I do not need the specifics, I simply need a yes/no result from each operation. Is there a better way?
why not
boolean cleanupfirst = false;
try {
op1 ();
cleanupfirst = true;
op2 ();
cleanupfirst = false;
op3 ();
} catch (Exception e) {
if (cleanupfirst)
cleanup ();
return;
}
You're over-thinking it.
4 minor adjustments.
Let Opn() return a boolean for success or failure, rather than throwing an Excpetion.
Let CleanupFirst handle program termination (you can rename it to clean exit if you want). The new parameter passed to CleanExit is the System.exit code.
Use System.Exit to return a proper return code to the OS, so you can use it in scripting.
It does not seem like your program has a successful path.
if (!op1())
System.exit(1); // <- send a failed returncode to the OS.
if(!op2())
cleanExit(2);
if (!op3())
System.exit(3); // <- send a failed returncode to the OS.
if (!op4())
cleanExit(4);
if (!op5())
cleanExit(5);
cleanExit(0);
More methods for better readability:
public void myMethod() {
try {
tryOp1();
tryOp2();
...
} catch(Exception ignore) {}
}
public void tryOp1() throws Exception {
op1();
}
public void tryOp2() throws Exception {
try {
op1();
} catch (Exception e) {
cleanUp();
throw e;
}
}
Not sure if this has already been answered, but.
I know that in java there is the try, catch and finally blocks, but is there one which is only called if try has no errors/exceptions?
Currently after stating the command that needs to be run, I'm setting a boolean to true, and after the try and catch block, the program checks for if the boolean is true.
I'm pretty sure that there is a much simpler way, help is appreciated!
Just put your code after the try...catch block and return in the catch:
boolean example() {
try {
//dostuff
} catch (Exception ex) {
return false;
}
return true;
}
This would also work if you put the return true at the end of the try block as the code would jump to the catch on error and not execute the rest of the try.
void example() {
try {
//do some stuff that may throw an exception
//do stuff that should only be done if no exception is thrown
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
No, there is no block called only if no exceptions were raised.
The catch block is called if there were exceptions, finally is called regardless.
As stated, you can emulate such a beast with something like:
bool completed = false;
try {
doSomeStuff();
completed = true;
} catch (Exception ex) {
handleException();
} finally {
regularFinallyHandling();
if (completed) {
thisIsTheThingYouWant();
}
}
but there's nothing built into the language itself that provides this functionality.
I'm working on some server-side code that wraps all exceptions before passing them to the client side, due to this all client facing methods have the following code
try{
DoSomething();
} catch (ExceptionA e) {
throw new CustomException(AType, e);
} catch (ExceptionB e) {
throw new CustomException(BType, e);
} catch (Exception e) {
throw new CustomException(Unexpected, e);
}
to have this repeated in every method seems to violate the DRY principle and I was wondering what the best way to refactor it would be. For instance I was thinking a wrapper method such as:
private void wrapException(Exception e) {
if (e instanceof ExceptionA) {
throw new CustomException(AType, e);
}
etc...
Take a look at AspectJ soften exception.
Also look at Guava's Throwables.
There is also Lamboks sneaky exception.
The other option is to use Anonymous object instances aka closures.
public abstract class Wrapper {
public void execute() {
try {
// do some boiler plate before
this.wrap();
// do some boiler plate after.
} catch (ExceptionA | ExceptionB ex) {
Type t = determineType(ex);
throw new CustomException(t, ex);
}
}
public void abstract wrap();
}
Now in your code you do something like:
new Wrapper() {
public void wrap() {
DoSomething();
}
}.execute()
This is possible in Java7 and up:
http://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html
Copy-paste example from above doc:
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
This is one way to go about it:
Exception caughtEx = null;
String extraInfo = null;
try{
DoSomething();
} catch (ExceptionA e) {
caughtEx = e;
extraInfo = AType;
} catch (ExceptionB e) {
caughtEx = e;
extraInfo = BType;
} catch (Exception e) { // catching Exception is usually a bad idea, just let it bubble up without catching...
caughtEx = e;
extraInfo = Unexpected;
}
if (caughtEx != null) throw new CustomException(extraInfo, caughtEx);
I have a try with several different catches after it. I have some "cleanup" code that only should be run if there was an exception thrown. I could add the same code to each exception, but that becomes a maintenance nightmare. Basically, I'd like something like the finally statement, but for it to only run if an exception was thrown.
Is this possible?
There is no direct support for this unfortunately. How about something like this
boolean successful = false;
try {
// do stuff
successful = true;
} catch (...) {
...
} finally {
if (!successful) {
// cleanup
}
}
The only thing I can think of is to set a variable in each catch and then check for that variable in finally.
Pseudocode:
Boolean caught = false;
try {
//risky code here
catch(err) {
caught = true;
// Do other stuff
}
catch(err) {
caught = true;
// Do other stuff
}
catch(err) {
caught = true;
// Do other stuff
}
finally {
if (caught) {
// Do clean up
}
}
I could add the same code to each exception, but that becomes a maintenance nightmare.
Or if you blot out the 'exception':
I could add the same code to each [place], but that becomes a maintenance nightmare.
This is what methods are made for.
private void cleanup() { /* clean up */ }
...
try {
// oh noes
} catch (MyException me) {
cleanup();
} catch (AnotherException ae) {
cleanup();
}
Maintenance hassle gone!
Why don't you just use simple try & catch?
try
{
foo();
}
catch(Exception1 e1)
{
dealWithError(1);
}
catch(Exception2 e2)
{
dealWithError(2);
}
catch(Exception3 e3)
{
dealWithError(3);
}
...
private void dealWithError(int i)
{
if(i == 1) // deal with Exception1
else if(i == 2) // deal with Exception2
else if(i == 3) // deal with Exception3
}
You could try wrapping two layers of exception handlers, and rethrow the exception after you have done the common handling:
try {
try {
// your code goes here
} catch (Throwable t) {
// do common exception handling for any exception
throw t;
}
} catch (NullPointerException nx) {
// handle NPE
} catch (Throwable t) {
// handle any other exception
}
Not sure I really like this solution though... feels like a bit of a hack. I'd probably rather see the Exception explicitly handled in each instance, even if this means repeating a call to some kind of shared cleanup function.