I have two APIs (say create and update) that calls the same serviceA. serviceA has a conditional block that will only be called in case of update. serviceA throws a number of different exceptions but some of them will only be thrown within the conditional block called by update I am looking for suggestions for exception handling in my APIs (create and update). What is a recommended practice here? I don't want to have duplicate exception handling logic but if I extract the error handling logic, I might have to catch exceptions that are only applicable to update for create as well.
public class ServiceA {
void upsert(Request request) {
//some common operations for create and update
if (request.action == "UPDATE") {
//update
if (someUpdateErrorCondition) {
throw new ExceptionA();
} elseif (someOtherUpdateErrorCondition) {
throw new ExceptionB();
}
...
}
if (someErrorCondition) {
throw new ExceptionC();
} elseif (someOtherErrorCondition) {
throw new ExceptionD();
}
...
}
Appreciate your help!
Not sure if I correctly understood the problem, but if you have common exceptions to handle as well as specific exceptions then you could use a lambda for common error handling.
There's various flavors of the same approach which is to control the execution with a shared component, whether you use function composition, the decorator pattern, etc.
E.g. (non-java pseudo-code)
function process1() {
withCommonErrorHandling(() => {
try {
//could throw CommonError or Process1Error
} catch (Process1Error e) {
//handle
}
});
}
function process2() {
withCommonErrorHandling(() => {
try {
//could throw CommonError or Process2Error
} catch (Process2Error e) {
//handle
}
});
}
function withCommonErrorHandling(fn) {
try { fn() }
catch (CommonError e) {
//handle
}
}
Related
I should know this, but for some reason I can't figure it out right now.
Is there a way to rewrite this code to avoid instanceof?
try {
//Exceptions may happen
} catch (Exception1 exception1) {
//do stuff only in case of Exception1
} catch(Exception e) {
// do stuff in all exception cases except Exception1
if (e instanceof Exception2) {
// do stuff only in case of Exception2
}
}
If you're going to have your exception handling for Exception inline, and don't want to repeat it, then the only solution is the OP solution.
However, if you can put the common exception handling into a function, then this would be neat:
try {
//Exceptions may happen
} catch (Exception1 exception1) {
//do stuff only in case of Exception1
} catch(Exception2 e) {
doCommonStuff();
doException2Stuff();
} catch(Exception e) {
doCommonStuff();
}
However, the above may lead to a small problem in terms of whether you want to pass control to outside of the try/catch block, or whether you're hoping to return a value, or even throw another exception.
You may find that although all paths of your code DO throw an exception, that the above construct, of using common exception handler methods, may look to the compiler like some control paths don't.
You can, therefore, express a common exception handler, that always throws an exception like this:
private <T> T throwLastException(Exception2 input) {
// blah blah blah
throw new SomeException();
}
and this can be called as part of a return statement that appears to guarantee the calling function returns a value, when in fact it's just telling the compiler not to worry :)
Without any further context IMO the following is good enough:
try {
//Exceptions may happen
} catch (Exception1 exception1) {
//do stuff only in case of Exception1
} catch (Exception2 exception2) {
some_method();
}
catch(Exception e) {
some_method();
}
Where some_method would encapsulate the code related with "// do stuff in all exception cases except Exception1"
Consider encapsulating common code between catch clauses 2 & 3 on some method, for instance:
try {
//code
} catch (Exception1 e1) {
// specific code for exception 1
} catch (Exception2 e2) {
// specific code for exception 2
method();
} catch (Exception e) {
method();
}
Catch two types of exception in one block with the "|" operator.. And maybe you can execute code that you have to execute in any case in the finally statement. That are all options you have, and i think creating a method and calling it isn't a option, when you're trying to make your code more readable, what I think you're trying to do
try {
//code
} catch (Exception1 | Exception2 e2) {
// specific code for exception 1 & 2
} catch (Exception e) {
// handle other exceptions
} finally {
// execute in any case
}
Don't really know if the title fits the problem that I'm trying to solve but here it goes (feel free to modify it for something that makes more sense).
Actually I'm appending String related operations within a Consumer, so that when requested the value is transformed within the chain. However, I see the same exception being thrown in multiple methods and I would like to compress that exact same try/catch clause in an upper level, so that methods only contain the new Consumer definition to be appended.
public static class Clazz {
private Consumer<String> modifications;
public Clazz() {
// ...
}
public void addOp() {
this.modifications = modifications.andThen(item -> {
try {
item.toUpperCase();
} catch (Exception e) {
// logging and exception handling - Merge in common lambda?
}
});
}
public void anotherOp() {
this.modifications = modifications.andThen(item -> {
try {
item.toLowerCase();
} catch (Exception e) {
// logging and exception handling -- Merge in common lambda?
}
});
}
}
Would there be any option to compress all those exception clauses in an upper class? Which is the approach when simplifying lambda try/catch clauses?
I have a method. This method has a catch block.
// pseudo code
private void function() {
try {
// something
} catch(exception e) {
// error handling
}
}
This method is called in another class
In one scenario the class is implemented with its own catch block
// pseudo code
private void anotherFunction() {
try {
function();
} catch {
//another catch block
}
Now I just want to execute the code in the catch block where the function is called and don't call the catch block implemented in the class. Is there a way to do this or should I think about another approach?
A workaround is to move your logic to another method which doesn't handle that exception, but just passes it upwards e.g:
public void unsafeFunction() throws Exception{
// something
}
And then call that method from your both classes, where both handle the exception differently:
public void function(){
try {
unsafeFunction();
} catch(Exception e){
// error handling
}
}
And:
public void anotherFunction(){
try {
unsafeFunction();
} catch(Exception e){
// other error handling
}
}
That way you leave what should be done with the exception to the caller.
Another completly different approach is to use the java.util.function.Consumer interface from Java 8 and accept that in your function, the caller then can just pass the error-handler into it:
public void function(Consumer<? super Exception> errorHandler){
try{
// something
} catch(Exception e){
// delegate to handler
errorHandler.accept(e);
}
}
Which can then be used like this:
public void someFunction(){
function(e -> {
// error handling
});
}
And:
public void anotherFunction(){
function(e -> {
// other error handling
});
}
There must be a reason to catch the exception. Say that reason can be tested in a separate method:
private boolean testCircumstanceThrowingException() {
if (exceptionalCircumstance) {
return false;
} else {
return true;
}
}
then you can implement your original function as:
private void functionCatchingException(){
if (testCircumstanceThrowingException()) {
//error handling
}
function();
}
and
private void anotherFunction() {
if (testCircumstanceThrowingException()) {
//error handling
}
function();
}
this way, during the normal running of the application, no exceptions are thrown. And this is how it should be because exceptions are for exceptional circumstances. If you somehow get to a state where exceptions are expected then something is wrong.
You should only rely on excpetions if there is no other way. For instance, if your specific use of the function cannot test the exceptional circumstance and you're required to use function. Take a look at Lino's answer for possible workarounds.
Java purists will notice that you can simply do return exceptionalCircumstance; but this code was just intended to show that a function that tests for the exceptional circumstance may be required; the result may not even be a boolean.
Of course you may now want to rename functionCatchingException :)
In your first code snippet:
private void function() {
try {
// something
}
catch (Exception e) {
// error handling
throw e; // rethrow?
}
}
you basically have two options with Java. You can either swallow the exception, or you can rethrow it. If you swallow it, then the caller of this method won't see an exception. If you rethrow, then the caller would also get an exception.
If neither of these behaviors are what you really want, then you might want to rethink your design.
You can throw the exception to the caller method using the keyword throw:
private void function(){
try{
//something
} catch(Exception e){
//error handling
throw e;
}
}
Then your anotherFunction() catch block will be executed.
You can learn more from here: The Java Tutorials
For a project I've been working on, we have some blocks that look like this:
Class A:
try {
callSomeMethod();
}
catch (Exception e) {
throw new SomeCustomExceptionTypeForMetrics("");
}
However, I was tasked with replacing all instances where we catch generic exceptions with only specific "expected" types of exceptions.
The problem is callSomeMethod() has something like this
Class B:
try {
if (someCondition...) {
}
else {
//failed
throw new RuntimeException("Timeout while waiting for results")
}
}
catch(InterruptedException e) {
// do some failure stuff here
throw new RuntimeException("Something here");
}
Ideally, my group has asked me to change as little as possible, and I can't change the signature for callSomeMethod(), but they also don't want to just catch any RuntimeException in Class A since they don't want to catch just any type of RuntimeException - only the ones we're excepting from Class B.
What is the best way to handle this?
Supposing that your callSomeMethod's signature contains throws Exception, and you can't change it: Change the RuntimeExceptions in the method to a custom Exception class, and then in Class A:
try {
callSomeMethod();
}
catch (Exception e) {
if(e instanceof CustomException)
//Log it or something, for metrics?
}
This is kind of silly, but might be necessary if you can't change the method signature. (If you can change it, you could catch the CustomException directly.) You could even make a method in your logger that takes an Exception, checks what type it is, and acts accordingly. Then just use this method in every catch statement that you need to edit.
While designing this solution, keep in mind that RuntimeExceptions don't need to be caught. It could save you some trouble.
If you chnage your code in class B as below
try {
if (someCondition...) {
}
else {
//failed
throw new MyRuntimeException("Timeout while waiting for results")
}
}
catch(InterruptedException e) {
// do some failure stuff here
throw new MyRuntimeException("Something here");
}
and define MyRuntimeException as :
class MyRuntimeException extends RuntimeException{
..
}
In class A, you only need to catch MyRuntimeException exception .
Hope this solve your problem!!
I have some private method in a class which has equal exception handling. Their body code raises equal exception types and the code handling is the same.
private void method1() {
try {
//make_the_world_a_better_place
}
catch(IOException ioe) {
// ...
}
}
private boolean method2(String str) {
try {
//make_a_cheesecake
}
catch(IOException ioe) {
// ...
}
}
Which is the best way to externalize the common exception handling, so when I make a change in the exception handling code of one of the methods the change will propagate to other methods? Template Method pattern would be handy in this situation, but I don't want go deep into the class hierarchy.
EDIT: There are several catch clauses, not only one like in the example.
Create an interface:
public interface Executor {
void exec() throws Exception;
}
in your class:
checkForExceptions(new Executor() {
#Override
public exex() throws Exception {
method1();
}
});
private void checkForExceptions(Executor ex) {
try {
ex.exec();
} catch (Exception e) [
/// handling
}
Your instinct is good - DRY is a good thing. But don't do this. Your code will be harder to read.
Make sure your catch blocks are really handling the exception and not just swallowing it. If your class isn't providing remediation, I'd say it'd be better to throw it and let clients figure out what to do.
You can create a handleException(IOException ioe) method which they both call.
I was thinking for a try-catch-handling at one place and the method's logic between them, but I guess the world then would be too perfect. Actually I have several catch clauses in the methods.