Retry after Spring throws DataAccessException not working - mysql

I am facing a very peculiar situation. I am using hibernate template with spring 3.0.5 for DB operations. When I try to insert a User model the first time, a DataAccessException is thrown, which I catch. Now I wish to retry the same DB operation for say 3 times. The second time when it, no exception is thrown.
Here is the code:
package com.user.profile.dao;
#Repository("userProfileDAOImpl")
public class UserProfileDAOImpl implements IUserProfileDAO {
#Autowired
private HibernateTemplate hibernateTemplate;
public Long insertUserProfileData(User user) throws AppNonFatalException {
Long id = null;
int retryCount = 0;
while (retryCount < 3) {
try {
id = (Long)hibernateTemplate.save(user);
}
catch (DataAccessException e) {
e.printStackTrace();
retryCount++;
System.out.println("Retry Count = " + retryCount);
if (retryCount > 3) {
throw new AppNonFatalException(e.getLocalizedMessage(), "10000", e.getMessage(), e);
}
}
catch (Exception e) {
/* not coming inside this block too second time onwards */
System.out.println("Pure Exception");
}
}
return id;
}
}
I read that RuntimeExceptions should not be caught. Then how do I retry the operation. Should I retry at the service layer? Am I missing something? Any help is appreciated.

From https://community.oracle.com/docs/DOC-983543:
Unchecked exceptions are exceptions
that do not need to be declared in a
throws clause. They extend
RuntimeException. An unchecked
exception indicates an unexpected
problem that is probably due to a bug
in the code.
Since DataAccessException is a RuntimeException, you might want to check what is the real cause of the exception and fix it instead of catching it and retry the operation.

Related

What is the purpose of multiple "catch" blocks in exception handling

Why we need multiple "catch" blocks even though we can write one generic
exception?
Is that important to know all the exception types and their purposes to make a good piece of code?
I googled a lot but still have confusions in exception handling. Any good example?
Generic Exception:
try{
//some code
}
catch(Exception e){
//print e
}
//that's it.
Multiple catches
try{
//some code
}
catch(IOException e){
}
catch(SQLException e){
}
There are several advantages of using multiple exceptions:
General exceptions will not let you know the exact root cause of the issue especially if many steps/checks involved in a method implementation. Also, If the exception occurs due to various reasons, you need to throw the different types of exceptions from your caller method implementation.
Eg: You can throw custom exceptions.
Here is your service code:
public void Login(string username, string password)
{
if(string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
{
throw InvalidUserNameException();
}
if(!IsInternetAvaialable())
{
throw NoInternetAvailableException()
}
else
{
//Implement though your login process and if need use various custom exceptions or throw the exception if occurs.
}
}
public class InvalidUserNameException : Exception
{
public InvalidUserNameException()
{
}
public InvalidUserNameException(string message)
: base(message)
{
}
public InvalidUserNameException(string message, Exception inner)
: base(message, inner)
{
}
}
Caller Method:
try {
...
} catch(InvalidUserNameException e) {
// Show Alert Message here
} catch(NoInternetAvaibleException e) {
// Show Alert Message with specific reason
}
catch(Exception e) {
// Other Generic Exception goes here
}
Reference:
https://learn.microsoft.com/en-us/dotnet/standard/exceptions/how-to-create-user-defined-exceptions
1. Why we need multiple "catch" blocks even though we can write one generic exception?
Sometimes you might need to specify what causes the problem.
For example,
try {
...
} catch(IOException e) {
// Print "Error: we cannot open your file"
} catch(SQLException e) {
// Print: "Error: we cannot connect to the database"
}
With different errors, users can understand what went wrong easily.
If we go with
try {
...
} catch(Exception e) {
// Print "Error: " + e.
}
It's harder for the users to figure out what went wrong.
Also, we can send the users to different pages accordingly to the error if we use multiple catch-es.
2.Is that important to know all the exception types and their purposes to make a good piece of code?
Personally, I would go with important exceptions such as IO, DB, etc. that can cause serious trouble. For others, I would catch with general exception.

Handling Runtime Exception in CompletableFuture in java8

Below is the sample code I'm using to understand exception handling in completablefuture in java8.
If we make use of exceptionally method as per doc,
exceptionally method catches even runtime exception as well and proceeds to last block in the pipeline.
if we don't use exceptionally method then, it justs prints running and exits.
Correct me if my understanding isn't correct.
Question is Lets say if i want to throw runtime exception and want application to stop. Basically if i throw Runtime exception , it shouldn't proceed to next block in pipeline. How should i do that. Any pointers are helpful.
public static void main(String[] args) {
final CompletableFuture<String> retrieveName = CompletableFuture.supplyAsync(() -> {
System.out.println("running");
int i = 0;
if(i == 0) {
throw new RuntimeException("ding");
}
return "test";
}).exceptionally(it -> {
System.out.println(it.getMessage());
return "empty";
}).thenApply(it -> {
System.out.println("last block" + it);
return "dummy";
});
}
Try this:
public static void main(String[] args) {
try {
final CompletableFuture<String> retrieveName = CompletableFuture.supplyAsync(() -> {
System.out.println("running");
int i = 0;
if (i == 0) {
throw new RuntimeException("ding");
}
return "test";
}).exceptionally(it -> {
if (it.getMessage().contains("ding")) {
throw (RuntimeException) it;
}
System.out.println(it.getMessage());
return "empty";
}).thenApply(it -> {
System.out.println("last block" + it);
return "dummy";
});
retrieveName.join();
} catch (Exception e) {
System.out.println("main() exception, cause=" + e.getCause());
}
}
This is the output:
running
main() exception, cause=java.lang.RuntimeException: ding
I made 3 small changes to your code:
Wrapped it all in a try-catch
Threw a RuntimeException in exceptionally() for the "ding" exception.
Added a call to retrieveName.join(). From the Javadoc for CompletableFuture.join():
public T join​()
Returns the result value when complete, or throws an (unchecked) exception if completed exceptionally.
Update based on OP feedback ------->
Lets say if i want to throw runtime exception and want application to
stop. Basically if i throw Runtime exception , it shouldn't proceed to
next block in pipeline. How should i do that.
You can achieve what you want with just 2 changes to your code:
[1] Completely remove the exceptionally() callback so the CompletableFuture (CF) terminates with an exception. In exceptionally() in the OP code the exception was being swallowed rather than rethrown, and returning a CF, so the thenApply() method was still performed.
[2] Add a call to retrieveName.join() at the end of main(). This is a blocking call, but since the thread had terminated with an exception that 's not really relevant for the sample code. The join() method will extract the thrown RunTimeException and re-throw it, wrapped in a CompletionException.
Here's your modified code:
public static void main(String[] args) {
final CompletableFuture<String> retrieveName = CompletableFuture.supplyAsync(() -> {
System.out.println("running");
int i = 0;
if(i == 0) {
throw new RuntimeException("ding");
}
return "test";
}).thenApply(it -> {
System.out.println("last block" + it);
return "dummy";
});
retrieveName.join();
}
Notes:
This is not how to do things in Production. The blocking call from join() was not a problem here, but could be for a long running CF. But you obviously can't extract the exception from the CF until it is complete, so it makes sense that the join() call blocks.
Always bear in mind that main() is not running in the same thread(s) as the CF.
An alternative approach (if viable) might be to handle all the necessary post-exception actions (logging, etc,) within exceptionally() and then terminate normally with a suitable return value (e.g. "Exception handled!") rather than propagating the exception.
You can check whether the CF is still running by calling the non-blocking isDone() method. You can also check whether the CF ended with an exception (isCompletedExceptionally()) or was cancelled(isCancelled​()).

Where can I get the exception throwed within the subscribe() method?

I'm using rxAndroid.
I've read many documents, but still not found the solution, and maybe I missed it,
so please give me a guide.
Here I created an observable that might throw an exception in subscribe method.
return Observable.create(new ObservableOnSubscribe<Project>() {
#Override
public void subscribe(#NonNull ObservableEmitter<Project> e) throws Exception {
e.onNext(projectRepository.readDetails(project.getId()));
e.onComplete();
}
});
I use repository pattern to get the project details,
but the problem is all of the repository methods might throw an exception,
projectRepository.readDetails(project.getId())
And I couldn't find anyway to handle the exception throwed in the method subscibe(), Observer's onError() will not get any notification of it.
Thanks.
When creating an observable manually, you have to catch any exception and pass them to the onError() manually:
return Observable.create(new ObservableOnSubscribe<Project>() {
#Override
public void subscribe(#NonNull ObservableEmitter<Project> e) throws Exception {
try {
e.onNext(projectRepository.readDetails(project.getId()));
e.onComplete();
}
catch (Exception ex) {
e.onError(ex);
}
}
});
Alternatively you should be able to use fromCallable() to avoid having to create the observable manually:
Observable.fromCallable(() -> projectRepository.readDetails(project.getId()));
This will signal onError() if the call should fail.

test "handled exceptions" junit

I have a method with a handled exception:
public boolean exampleMethod(){
try{
Integer temp=null;
temp.equals(null);
return
}catch(Exception e){
e.printStackTrace();
}
}
I want to test it
public void test_exampleMethod(){}
I have tried
#Rule
public ExpectedException expectedException=ExpectedException.none();
public void test_exampleMethod(){
expectedException.expect(JsonParseException.class);
exampleMethod();
}
but that doesnt work because the exception is handled inside.
I also tried
#Test(expected=JsonParseException.class)
but same issue...the exception is handled
I know that I can just do
assertTrue(if(exampleMethod()))
but it will still print the stack trace to the log. I would prefer clean logs...Any suggestions?
You cannot test what a method is doing internally. This is completely hidden (unless there are side effects, that are visible outside).
The test can check that for a specific input the method returns a expected output. But you can not check, how this is done. So you have no way to detect if there was a exception that you have handled.
So: either don't handle the exception (let the test catch the exception), or return a special value that tells you about the exception.
Anyway, I hope your real exception handling is more sensible than in your example.
If the method does not throw an exception you cannot expect to get one!
Below an example how write a Junit Test for a method that throws an Exception:
class Parser {
public void parseValue(String number) {
return Integer.parseInt(number);
}
}
Normal test case
public void testParseValueOK() {
Parser parser = new Parser();
assertTrue(23, parser.parseValue("23"));
}
Test case for exception
public void testParseValueException() {
Parser parser = new Parser();
try {
int value = parser.parseValue("notANumber");
fail("Expected a NumberFormatException");
} catch (NumberFormatException ex) {
// as expected got exception
}
}

ServiceStack catch (WebServiceException ex) - has wrong ErrorCode

In my ServiceStack service, I throw an exception that has an inner exception. When I caught a WebServiceRequest on the client side, the ErrorCode was the inner exception type name.
This is bad for me because it doesn't allow me to respond to the specific exception type that was thrown on the server.
I'm failing to see why ServiceStack was designed this way. It's pretty typical to catch lower level exceptions and wrap them with more informative and sometimes end-user friendly exceptions.
How can I change the default behavior so it uses the surface level exception and not the inner-most?
After looking at the first example at https://github.com/ServiceStack/ServiceStack/wiki/Error-Handling, I decided to check out at DtoUtils.HandleException, which looks like this:
public static object HandleException(IResolver iocResolver, object request, Exception ex)
{
if (ex.InnerException != null && !(ex is IHttpError))
ex = ex.InnerException;
var responseStatus = ex.ToResponseStatus();
if (EndpointHost.DebugMode)
{
// View stack trace in tests and on the client
responseStatus.StackTrace = GetRequestErrorBody(request) + ex;
}
Log.Error("ServiceBase<TRequest>::Service Exception", ex);
if (iocResolver != null)
LogErrorInRedisIfExists(iocResolver.TryResolve<IRedisClientsManager>(), request.GetType().Name, responseStatus);
var errorResponse = CreateErrorResponse(request, ex, responseStatus);
return errorResponse;
}
The very first instruction replaces the exception with it's inner exception. I'm not sure what the the thinking was with that. It seems counter intuitive to me and so I just re-implemented the method in my AppHost class, removing that first if statement block:
public override void Configure(Container container)
{
ServiceExceptionHandler += (request, exception) => HandleException(this, request, exception);
}
/// <remarks>
/// Verbatim implementation of DtoUtils.HandleException, without the innerexception replacement.
/// </remarks>
public static object HandleException(IResolver iocResolver, object request, Exception ex)
{
var responseStatus = ex.ToResponseStatus();
if (EndpointHost.DebugMode)
{
// View stack trace in tests and on the client
responseStatus.StackTrace = DtoUtils.GetRequestErrorBody(request) + ex;
}
var log = LogManager.GetLogger(typeof(DtoUtils));
log.Error("ServiceBase<TRequest>::Service Exception", ex);
if (iocResolver != null)
DtoUtils.LogErrorInRedisIfExists(iocResolver.TryResolve<IRedisClientsManager>(), request.GetType().Name, responseStatus);
var errorResponse = DtoUtils.CreateErrorResponse(request, ex, responseStatus);
return errorResponse;
}
This is obviously not ideal, since I had to copy a bunch of code that is totally unrelated to the problem that I had with the original implementation. It makes me feel like I have to maintain this method whenever I update ServiceStack. I would love to here of a better way to accomplish this.
Anyway, I have the exception handling that I like in my client code:
catch (WebServiceException ex)
{
if (ex.ErrorCode == typeof (SomeKindOfException).Name)
{
// do something useful here
}
else throw;
}
It doesn't seem like you'll have to maintain a bunch of code. You're writing one method to implement your own error handling. You could try calling DtoUtils.HandleException(this, request, exception) in your own method and modify the HttpError object returned. Not sure you have access to change all properties/values you're looking for.
public static object HandleException(IResolver iocResolver, object request, Exception ex)
{
HttpError err = (HttpError)DtoUtils.HandleException(this, request, ex);
err.Reponse = ex.InnerException;
}