In my resource method i will get the below exception
#Override
public Response registerByDebitCard(RegistrationRequest registrationRequest,BeanFilter beanFilter) {
try {
RegistrationResponse registrationResponse = registrationService.doRegister(registrationRequest, beanFilter);
return Response.ok(registrationResponse).build();
} catch (CannotCreateTransactionException e) {
LOGGER.error("Error Message is :: {}", e.getMessage());
throw new RegistrationFailureException("MPYR0012", "Due to database technical problem signup failed");
}
}
If i catch above exception it works.
I try to catch this exception using my custom exception class i can't able to catch.Below is my custom Exception class.
public class TransactionManagerDBException extends CannotCreateTransactionException {
/**
* #param msg
*/
public TransactionManagerDBException(String msg) {
super(msg);
}
public TransactionManagerDBException(String msg, Throwable cause) {
super(msg, cause);
}
}
My Resource Method:
#Override
public Response registerByDebitCard(RegistrationRequest registrationRequest,BeanFilter beanFilter) {
try {
RegistrationResponse registrationResponse = registrationService.doRegister(registrationRequest, beanFilter);
return Response.ok(registrationResponse).build();
} catch (TransactionManagerDBException e) {
LOGGER.error("Error Message is :: {}", e.getMessage());
throw new RegistrationFailureException("MPYR0012", "Due to database technical problem signup failed");
}
}
Now i am unable to catch this exception.Is their anything wrong in my exception handling.please explain what's wrong with my approach
Any help will be greatly appreciated!!!!
Your TransactionManagerDBException IS-A CannotCreateTransactionException. But the reverse is not true. If your registrationService does throw a CannotCreateTransactionException, it is NOT a TransactionManagerDBException.
If you cannot change the doRegister method to throw a TransactionManagerDBException, you can only use a catch block using CannotCreateTransactionException.
Related
I have written some logic and custom validation in Validator initialize method.
But when exception occurs , custom exception was thrown but override by ValidationException
eg. HV000032: Unable to initialize ........
public class CustomValidator implements ConstraintValidator<CustomClass, CharSequence> {
#Override
public void initialize(CustomClass annota) {
try {
//code
} catch (Exception e) {
throw new CustomException("custom error ", e); <-- this exception is override by javax.validation.ValidationException...
}
}
I want to get my custom exception and message . How can I implement that ...
In order to get your custom exception and message, you can catch the ValidationException thrown by the validation framework and extract your custom exception and message from it.
Something like this should work.
public class CustomValidator implements ConstraintValidator<CustomClass, CharSequence> {
#Override
public void initialize(CustomClass annota) {
try {
// code
} catch (ValidationException e) {
/* if an exception is thrown in the initialize method, the validation framework will not execute the isValid method. */
throw new CustomException("validation error", e);
} catch (Exception e) {
throw new CustomException("custom error", e);
}
}
#Override
public boolean isValid(CharSequence value, ConstraintValidatorContext context) {
try {
// validation logic
return true;
} catch (CustomException e) {
// catch and rethrow your custom exception
throw e;
} catch (ValidationException e) {
// catch and extract your custom exception and message
Throwable cause = e.getCause();
if (cause instanceof CustomException) {
CustomException customException = (CustomException) cause;
String message = customException.getMessage();
// do something with customException and message
}
throw e;
}
}
}
the isValid method is the main method used by the validation framework to determine if an object is valid or not, and it is necessary to implement it in order to define the validation logic. Even if an exception is thrown in the initialize method, the isValid method is still necessary and will be executed for valid objects.
That is expected behaviour for the validator. If you want to get other exception type then ValidationException, you can throw ConstraintDeclarationException out of your init method, which was somewhat designed to be used when the constraint declaration is wrong. Any other exceptions are wrapped into ValidationException, where a cause would be a thrown exception. So you could catch ValidationException in a place you are calling the validator and it's failing and then access your exception/message through getCause(). Something along next lines:
try {
validator.validate( object );
}
catch (ValidationException e) {
Throwable cause = e.getCause(); // <- your CustomException
}
Ideally, your initialize method should not throw any exceptions. The same is for the isValid - instead of throwing an exception, return false and a custom message explaining what failed:
#Override
public boolean isValid(CharSequence object, ConstraintValidatorContext constraintContext) {
if ( object == null ) {
return true;
}
boolean isValid = true;
try {
// some potentially failing logic:
}
catch (Exception e) {
isValid = false;
constraintContext.disableDefaultConstraintViolation();
constraintContext.buildConstraintViolationWithTemplate(
e.getMessage()
)
.addConstraintViolation();
}
return isValid;
}
i want to mock this service in controller, so that i can test this. how do i mock coreservice.getRelatedInfo to throw the given exceptions to test them.
i am trying to throw them but, i'm getting error. when i am testing for runtime exception it is working.
#PostMapping("/realtedcustomerinfo")
public ResponseEntity<List<CustomerInfoDTO>>
getRelatedCustomerInfo(#RequestBody RelatedCustomerInfo
relatedCustomerInfo) {
log.info("Start of getRelatedCustomerInfo() input {}",
relatedCustomerInfo);
List<CustomerInfoDTO> customerInfoDTOs = null;
try {
customerInfoDTOs =
coreService.getRelatedCustomerInfo(relatedCustomerInfo);
} catch (JsonParseException e) {
log.error("Exception details", e);
} catch (JsonMappingException e) {
log.error("Exception details", e);
} catch (IOException e) {
log.error("Exception details", e);
}
if (null == customerInfoDTOs) {
log.info("End of getRelatedCustomerInfo() return {}", customerInfoDTOs);
return new ResponseEntity<List<CustomerInfoDTO>>(new ArrayList<CustomerInfoDTO>(), HttpStatus.OK);
}
log.info("End of getRelatedCustomerInfo() return {}", customerInfoDTOs);
return new ResponseEntity<List<CustomerInfoDTO>>(customerInfoDTOs, HttpStatus.OK);
}
I have written a method which is returning some value in try statement. Inside catch I am calling handleException which will have conversion logic of understanding the exception and rethrowing new exception. Here handleException is always throwing exception, still the getXYZ() gives compile time error expecting return statement. I am not handling the exception, I am just throwing new exception so why does the method wants return statement.
public String getXYZ(String input) {
try {
return getFromDAO(input);
} catch (Exception e) {
handleException(e);
}
}
private void handleException(Exception e) {
try {
throw e;
} catch(SomeException se) {
throw new MyRuntimeException("MyException message", se);
} catch(SomeOtherException soe) {
throw new MyRuntimeException("MyException message", soe);
}
}
The other version of this method compiles.
public String getXYZ(String input) {
try {
return getFromDAO(input);
} catch (Exception e) {
throw e;
}
}
You are not throwing anything in the catch block, you're calling your handle function, which ultimately will result in a new exception being thrown, but the actual code in getXYZ is doing a function call in catch. What if you change handleException to later not throw an exception in some circumstances, what would getXYZ return then?
One way to solving this is making it clear to the compiler that you expect an exception to be thrown.
public String getXYZ(String input) {
try {
return getFromDAO(input);
} catch (Exception e) {
throw handleException(e); // compiles ok.
}
}
private RuntimeException handleException(Exception e) {
try {
throw e;
} catch(SomeException se) {
return new MyRuntimeException("MyException message", se);
} catch(SomeOtherException soe) {
return new MyRuntimeException("MyException message", soe);
} catch(RuntimeException re) {
return re;
} catch(Exception e2) {
return new MyRuntimeException("MyException message", e2);
}
}
BTW an alternative approach is to not wrap the Exception at all and leave the exception as it was.
public String getXYZ(String input) {
try {
return getFromDAO(input);
} catch (Exception e) {
throw rethrow(e); // compiles ok.
}
}
/**
* Cast a CheckedException as an unchecked one.
*
* #param throwable to cast
* #param <T> the type of the Throwable
* #return this method will never return a Throwable instance, it will just throw it.
* #throws T the throwable as an unchecked throwable
*/
#SuppressWarnings("unchecked")
public static <T extends Throwable> RuntimeException rethrow(Throwable throwable) throws T {
throw (T) throwable; // rely on vacuous cast
}
You may want to consider using the new java 8 lambda features to solve your problem as well. You will have to create a functional interface to declare the signature of the lambdas (with the relevant exceptions). Your handleException method will now be the one who runs the lambda and handles the exceptions.
public String getXYZ(String input) {
return handleKnownExceptions(() -> getFromDAO(input));
}
private <T> T handleKnownExceptions(ThrowingCode<T> throwingCode)
{
try {
return throwingCode.get();
} catch(SomeException se) {
throw new MyRuntimeException("MyException message", se);
} catch(SomeOtherException soe) {
throw new MyRuntimeException("MyException message", soe);
}
}
#FunctionalInterface
public interface ThrowingCode<T>
{
T get() throws SomeException, SomeOtherException;
}
There is a pattern I have seen a few times to handle this situation. You let the handleException method declare that it returns an exception. This is only indicative though, it will never return anything, it will always throw, just as before. The declared return type will allow the caller to use a throw handleException() statement, which will keep the compiler happy. The resulting code will be:
public String getXYZ(String input) throws Exception {
try {
return getFromDAO(input);
} catch (Exception e) {
throw handleException(e);
}
}
/**
* This method will never return normally, always throws.
*/
private Exception handleException(Exception e) throws Exception
{
try {
throw e;
} catch(SomeException se) {
throw new MyRuntimeException("MyException message", se);
} catch(SomeOtherException soe) {
throw new MyRuntimeException("MyException message", soe);
}
}
Im trying to return a JOptionePane message dialog for each one of the possible throws on my method:
public void add_note(String note) throws FileNotFoundException, IOException, InvalidFormatException{
... content ...
}
Is there any way to do this?
You could try something like :
public void add_note(String note) throws FileNotFoundException, IOException, InvalidFormatException
{
try
{
...content...
}
catch(FileNotFoundException fnfEx)
{
throw new FileNotFoundException("File was not found");
}
catch(IOException ioEx)
{
throw new FileNotFoundException("I/O exception");
}
catch(InvalidFormatException invEx)
{
throw new FileNotFoundException("Invalid format errror");
}
}
Where you put the message you want in the new exceptions and you print the exception message in the JOptionPane.
wrap your code inside try catch. Inside catch block for each exception type throw the message specific to each exception
Using a Try-Catch you can catch any exception and return something when an exception occurs. You should do this for all of your cases.
public void add_note(String note){
try {
//code
} catch (FileNotFoundException e) {
//return something
}
}
Instead of throwing exceptions, handle each individually in your method:
public JOptionPane add_note(String note) {
try {
...
} catch (FileNotFoundException fnfe) {
return ...;
} catch (IOException ioe) {
return ...;
} catch (InvalidFormatException ife) {
return ...;
}
}
I'll suggest you an alternative approach, as no one mentioned it.
I'd use AOP to catch those exceptions and show to the end user. You'll write a simple aspect, and dont mess your code with try and catch blocks.
Here is an example of such aspect
#Aspect
public class ErrorInterceptor{
#AfterThrowing(pointcut = "execution(* com.mycompany.package..* (..))", throwing = "exception")
public void errorInterceptor(Exception exception) {
if (logger.isDebugEnabled()) {
logger.debug("Error Message Interceptor started");
}
// DO SOMETHING HERE WITH EXCEPTION
logger.debug( exception.getCause().getMessage());
if (logger.isDebugEnabled()) {
logger.debug("Error Message Interceptor finished.");
}
}
}
If you don't know what Aspect Oriented Programming is definitely go check it out, this is very powerfull concept (just like OOP), spend some time to learn it.
If you want to show a dialog with the JOptionPane.showMessageDialog do as follows:
public void add_note(String note){
try {
//code
} catch (FileNotFoundException | IOException | InvalidFormatException e) {
JOptionPane.showMessageDialog(frame, e.getMessage(), "Title", JOptionPane.ERROR_MESSAGE);
//manage the exception here
}
}
when I debug the below code, there is an SmbException and goes catch block line sb.append(pLogger.reportError(pStr, e));, but it does not go into the method reportError().
what is the reason behind this. please advise if any changes.
try {
sfos = new SmbFileOutputStream(sFile);
} catch (SmbException e) {
sb.append(pLogger.rError(pathStr, e));
}
below is rError() method
public String rError(String pxString,Exception e){
String errorToMailStr=null;
abcd="Verifying # "+pxString+"::Error ["+e.getMessage()+"]";
logger.debug("Error when verifying # "+pxString+":Error ["+gMsg(e)+"]");
return abcd;
}
at line logger.debug("Issue "+pxString+":Error ["+gMsg(e)+"]");
is going to below method and ends.
public abstract class ReflectiveCallable {
public Object run() throws Throwable {
try {
return runReflectiveCall();
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
Based on what you have revealed here, there is a problem in getExceptionMsg()