We are monitoring our application by using timers. In case of an exception, we would like to catch the exception, stop the timer with an error, and rethrow the same exception without handling it. Which of the following catch objects would be the best approach to handle it?
Catch specific exceptions - will monitor only the specific exceptions but not all of them. Considered as best practice, but we will have to think and add all the possibilities each time we use a timer.
Catch Exception - will monitor all the Exceptions but not the Errors like OOM. Considered as bad practice, but in this case, we throwing back the exception, so we won't lose any data.
Catch Throwable - will monitor bot Exception and Error. Considered as bad practice, but in this case, we throwing back the exception, so we won't lose any data and we are not handling the Error.
public void run() {
Timer timer = monitoring.timer();
try {
timer.start();
// some logic
timer.stop(aSuccessTag());
// 1. catch specific exceptions
} catch (RuntimeException | IOException e) {
timer.stop(new TagList().tags(aFailureTag(e.getClass())));
throw e;
}
// 2. catch exception
} catch (Exception e) {
timer.stop(new TagList().tags(aFailureTag(e.getClass())));
throw e;
}
// 3. catch error and exception
catch (Throwable e) {
timer.stop(new TagList().tags(aFailureTag(e.getClass())));
throw e;
}
}
Thanks
Elad
Related
I am a beginner in API with Java, I am writing the RESTful APIs, and now I need to write the API Handler to handle the request from the front-end. Just noticed there are so many kinds of HTTP error when handling the request.
So I am wondering how to catch these exceptions with try-catch in Java.
I did one very basic try-catch to handle the InvalidRequestException, which refers to the exception from the client side.
#Override
public String handle(final APIGatewayProxyRequestEvent event) {
if (event.getHttpMethod().equalsIgnoreCase(HttpMethod.POST.name())) {
try{
FeatureRecord featureRecord = Jackson.fromJsonString(event.getBody(), FeatureRecord.class);
featureProcessor.createFeature(featureRecord);
return EMPTY_STRING;
} catch (Exception ex) {
throw new InvalidRequestException(ex);
}
}
Now I want to split the exception type to distinguish different HTTP exceptions, like this:
#Override
public String handle(final APIGatewayProxyRequestEvent event) {
if (event.getHttpMethod().equalsIgnoreCase(HttpMethod.POST.name())) {
try{
FeatureRecord featureRecord = Jackson.fromJsonString(event.getBody(), FeatureRecord.class);
featureProcessor.createFeature(featureRecord);
return EMPTY_STRING;
} catch (InvalidRequestException ex) {
throw new InvalidRequestException(ex);
} catch (ServiceInternalException ex) {
throw new ServiceInternalException(ex);
} ... ...
}
But I don't know how to write the catch sections.
I know there are many exception types from https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500, but how to handle them with try-catch? Do I need to write the new Exception type?
Catching more exception types
You can catch several exception types with a single catch if you catch their common ancestor class. For example
try {
//some code
} catch (Exception ex) {
//handling the catch
}
will catch all exceptions, so please be as general as possible, but still handle the errors properly, so catching Exception might be or might not be an option for you, depending on your situation.
Ways to handle an exception
You are catching several exception types and instead of handling them or throwing them, you throw an exception of the same type. For instance there is no reason to do this:
try {
//some code
} catch (InvalidRequestException ex) {
throw new InvalidRequestException(ex);
}
instead of this:
try {
//some code
} catch (InvalidRequestException ex) {
throw ex;
}
But if your catch is only throwing the same exception, then there is no point having the catch at all. You would need to make the errors user-friendly, that is, send a response to the user explaining the problems and then throw the exception. Or, you can avoid throwing the exception at all inside the catch and log some message instead.
Implementing your own Exception
This is of course an option and could be feasible if you have some custom error types.
I read in a Java book, that "Java will not allow you to declare a catch block for a checked exception type that cannot potentially be thrown by the try class body".
That makes sense so far.
But now I am asking myself why this code does compile:
try {
throw new Exception();
} catch (IOException e) {
} catch (Exception e) {
}
Java allows me to catch the IOException, but obviously it will never be thrown by the try-block.
Doesn't this example break the rule described in the Java book?
Java allows me to catch the IOException, but obviously it will never
be thrown by the try-block.
Because Exception is more general than IOException so the compiler understand that Exception can also be IOException.
Here is a contre example of what will happen if you try NumberFormatException instead of Exception
try {
throw new NumberFormatException();
} catch (IOException e) { // fail
} catch (Exception e) {
}
It fail because NumberFormatException is not general than IOException.
It is obvious to a programmer that reads this code, but i guess the compiler will deal with the throw statement the same way it would deal with a call to a method declared as throwing Exception, and in this case, the thrown exception could very well be an IOException.
I need to handle a particular exception and rest of all other exception which should gives us the same logging information but the level of logging should be different ( Former should be going to log.warn and the rest of them should be going to log.error)
try {
}
catch (someexception e) {
log.warn("some message")
-----some code----
}
catch(AllotherExceptions e) {
log.error("same message as above")
-----same code as above----
}
This needs to minimalized as the message is the same but need to make the rest of the code as a common code rather than writing it couple of times
You have several ways to do so. You can, as shown in previous answers, make successive catch statements like this :
try {
// Code that potentially throws multiple exceptions
}
catch (IOException ex) {
// Manage this particular exception case
}
catch (Exception ex) {
// Manage remaining exceptions
}
This way you'll be able to manage particular cases and define a point where all the exceptions related to the following actions will be managed. By putting this try statement early in your process (main loop, heavy service call...), you'll manage many exceptions but you'll not be able to manage specific cases since you won't know which particular actions threw them. By wrapping little specific actions (accessing files, requesting...), you'll be able to make very specific management of these exceptions.
As pointed in the answers, with Java >= 7 this syntax will work :
try {
// Code that potentially throws multiple exceptions
}
catch (IOException|SQLException ex) {
// Manage these particular exceptions
}
catch (Exception ex) {
// Manage remaining exceptions
}
This way is to be used when you need to manage different exceptions the exact same way. It's particularly helpful when a single action would throw different exceptions (ie accessing files) but you only want want to manage a few specific error cases in particular and not worrying about everything that can be thrown.
You can use multiple catch blocks to accomplish this, and catch Exception, the base class for all checked exceptions, last. For example:
try {
// Your code here.
} catch (SpecificException e) {
log.warn("Warning!", e);
} catch (AnotherSpecificException e) {
log.warn("Another warning!", e);
} catch (Exception e) {
log.error("Error!", e)
}
Just add several catch sections and finish with a catch all.
try {
// Some code
}
catch (IOException ex) {
logger.log(ex);
throw ex;
catch (Exception ex) {
logger.log(ex);
throw ex;
}
Read more here: Documentation
try{
//try something
} catch (SomeTypeException e){
//things
} catch (AnotherException e){
//AnotherThings
}
The following example, which is valid in Java SE 7 and later, eliminates the duplicated code:
try{
}
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
since java 7 you can do a try-Multicatch
try {
new Foo("").doSomething();
} catch (Exception1 | Exception2 e) {
e.printStackTrace();
}
I see below code in my legacy project where i am catching different types of exception and intention is just to logg them
try {
//somecode
}
catch (ProjectExceptionException1 e) {
log.error(e.getMessage(), e);
}
catch (ProjectExceptionException2 e) {
log.error(e.getMessage(), e);
}
catch (Exception e) {
log.error(e.getMessage(), e);
}
My point is if requirement is just to log the exception(whether its checked or unchecked), above code should be replaced by below one
that makes code simple and more readable. As per my understanding there is not point of catching specific exception and doing
same stuff under all. Is n't it? Let me know if i am missing something here.
try {
//somecode
}
catch (Exception e) {
log.error(e.getMessage(), e);
}
UPDATE:- even if are throwing specific exception on UI just to display the stack trace like below. Even then it does not make sense
.Basically if we want to handle the specific exception in special way then it would make sense. Right?
try {
//somecode
}
catch (ProjectExceptionException1 e1) {
throw e1;
}
catch (ProjectExceptionException2 e2) {
throw e2;
}
catch (Exception e3) {
throw e3;
}
Yes, it is perfectly fine to replace the top block with the single catch (Exception e), as long as you are only logging and do not need any Exception-specific handling.
As of Java 7 you can catch multiple exceptions and handle them all in the same way using the syntax:
catch (ProjectExceptionException1 | ProjectExceptionException2 ex)
So, if you want to log some exceptions but act on others, you could group the behaviours in this manner, assuming that the actions you would like to perform are the same. e.g. print stack trace then log for ProjectExceptionException1 and ProjectExceptionException2, but only log for everything else.
If you can upgrade the code to java 1.7, you could use the new multi-catch feature. It could look like this:
try {
//somecode
}
catch (ProjectExceptionException1 | ProjectExceptionException2 e) {
log.error(e.getMessage(), e);
}
You may want to reconsider catching Exception and only catching exceptions that you know would be thrown by the code in the try block so you don't just resort to logging unexpected exceptions.
Here's a link that goes into more detail about the feature with examples: http://www.oracle.com/technetwork/articles/java/java7exceptions-486908.html
I have read the bug detectors in findbugs website, http://findbugs.sourceforge.net/bugDescriptions.html
I want to write a test code and use Findbugs to detect the REC error.
But the findbugs cannot. Why? Could you help me to solve this?
Thanks,
Below is the description in Findbugs.
REC: Exception is caught when Exception is not thrown (REC_CATCH_EXCEPTION)
This method uses a try-catch block that catches Exception objects, but Exception is not thrown within the try block, and RuntimeException is not explicitly caught. It is a common bug pattern to say try { ... } catch (Exception e) { something } as a shorthand for catching a number of types of exception each of whose catch blocks is identical, but this construct also accidentally catches RuntimeException as well, masking potential bugs.
A better approach is to either explicitly catch the specific exceptions that are thrown, or to explicitly catch RuntimeException exception, rethrow it, and then catch all non-Runtime Exceptions, as shown below:
try {
...
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
... deal with all non-runtime exceptions ...
}
My code is:
public static void test1(){
int A[] = {1,2,3};
int result = 5/0;//divided by 0
int arrOut = A[0]+A[4];//index out of bound
System.out.println(arrOut);
System.out.println(result);
try {
} catch (RuntimeException e) {
// TODO: handle exception
System.out.println("Runtimeex throw");
throw e;
} catch (Exception e) {
// TODO: handle exception
System.out.println("An try error occurred: 0 cannot be divided");
}
}
The try is where the exception occur that you want to catch. However, since it is occurring out of the try block, the exception is not caught by the catch part, which is why FindBugs reporting it as a useless try {...} catch {...} code. The proper code should be as follows.
int A[] = {1,2,3};
try {
int result = 5/0;//divided by 0
int arrOut = A[0]+A[4];//index out of bound
System.out.println(arrOut);
System.out.println(result);
} catch (RuntimeException e) {
// TODO: handle exception
System.out.println("Runtimeex throw");
throw e;
} catch (Exception e) {
// TODO: handle exception
System.out.println("An try error occurred: 0 cannot be divided");
}
}