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;
}
Related
I am contemplating throwing a RuntimeException inside the catch block to solve the missing return statement.
What would be way to handle this situation?
I think throwing an exception of some kind instead of return some meaningless value. .
private String tryObjMapper(Object obj) {
try {
return objectMapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
//missing return statement
}
It depends on what you want to be the fallback/default value or error handling
You have 2 main options (with 2 sub options):
1.A.Throw the exception:
private String tryObjMapper(Object obj) throws JsonProcessingException {
return objectMapper.writeValueAsString(obj);
}
1.B.Rethrow RuntimeException (or custom unchecked exception)
private String tryObjMapper(Object obj) {
try {
return objectMapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
e.printStackTrace();
throw new RuntimeException("Failed to map obj +" obj, e);
}
}
2.A.Define a default value on error
private String tryObjMapper(Object obj) {
try {
return objectMapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;//or other default value
}
2.B.Define a default value with a single return statement:
private String tryObjMapper(Object obj) {
String retVal = null;//or other default value
try {
retVal = objectMapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return retVal ;
}
Consider logging exception using logger and not using e.printStackTrace()
I think that the best way to handle it is to return null at both catch block ant the end of the function. You must check the returnee from the function whether null or not before usage.
Note: This solution is suitable if only you can't change the signature of the function to declare that it throws an exception. Otherwise, go with the signature update.
I have two methods. Method A calls method B. I cannot change the exceptions of neither (homework demands). However, the 2 exceptions mean the exact same thing, so when I call method B on A, I already know that B's exception is not getting thrown. However, I still get the "unhandled exception" error from Eclipse. How can I avoid it?
Here are the methods
public void createProfile(Profile user) throws PEException {
Vector<Profile> p = new Vector<Perfil>();
try{
if (repository.search(user.getUsername()) == null) {
repository.register(user); //error on this line when I call the method on main
}
else {
throw new PEException(user.getUsername());
}
} catch (PEException e){
e.printStackTrace();
}
}
public void register(Profile user) throws UJCException {
try {
if (this.search(user.getUsername()) == null) {
this.users.add(user);
}
else {
throw new UJCException(user.getUsername());
}
} catch (UJCException e) {
e.printStackTrace();
}
}
I MUST NOT change the definitions of the methods (I can't throw UJCException on createProfile). Thanks in advance
You shouldn't be throwing the exceptions and then catching them inside the same method. That defeats the purpose of throwing the exception in the first place. the methods which calls your 2 methods should expect nothing (void) or the exception in the event that something went wrong. Make sure your methods createProfile() and register() can actually throw their exception so methods calling them can catch the exception and do whatever it is they need to when the exception is thrown.
public void createProfile(Profile user) throws PEException {
Vector<Profile> p = new Vector<Perfil>(); //not being used...
if (repository.search(user.getUsername()) == null) {
try{
repository.register(user);
}catch(UJCException e){
e.printStackTrace();
throw new PEException(user.getUsername());
}
}
else {
throw new PEException(user.getUsername());
}
}
public void register(Profile user) throws UJCException
{
if (this.search(user.getUsername()) == null) {
this.users.add(user);
}
else {
throw new UJCException(user.getUsername());
}
}
Now when you call these methods wrap the call in a try catch and catch the appropriate exception depending on which method was called
I am not able to throw a custom exception from within a try block. The exception doesn't return back to the caller, instead jumps out of the try-catch block and executes the remaining statements (return i; statement in the code).
I know that I don't need the try-catch block for the function "exceptionTester" to run. However I'd like to know the reason for this behaviour. exceptionTester(0) returns 0 instead of the exception being thrown.
public class Test {
public static int exceptionTester(int i) throws FAException{
try {
if (i==0) {
throw new FAException("some status code", "some message", null);
}
} catch (Exception e) {
// TODO: handle exception
}
return i;
}
public static void main(String[] args) {
try {
int in = exceptionTester(0);
System.out.println(in);
} catch (FAException e) {
System.out.println(e.getStatusCode());
}
}
}
public class FAException extends Exception {
private String statusCode;
public FAException(String statusCode, String message, Throwable cause){
super(message,cause);
this.statusCode = statusCode;
}
public String getStatusCode() {
return this.statusCode;
}
}
You are throwing a FAException and you want to re-throw it. Either remove the try-catch entirely, or catch that specific exception (if you insist) like
public static int exceptionTester(int i) throws FAException{
try {
if (i==0) {
throw new FAException("some status code", "some message", null);
}
} catch (FAException e) {
throw e; // <-- re-throw it.
}
return i;
}
It is also possible to throw a new FAException wrapping some other type of exception in the catch. Which might look like,
} catch (Exception e) {
throw new FAException("Status Code", "Original Message: " + e.getMessage(), e);
}
You are catching any exception that extends from Exception. FAException extends Exception so in your method exceptionTester(int) you are throwing FAException and immediatelly catching it. Since catch block does nothing, it continues in method processing. That's why return is reached.
If you want to catch any exception that can occur in method and rethrow it as your exception then:
public static int exceptionTester(int i) throws FAException{
try {
// some code that throws an exception
// e. g. dividing by zero, accessing fields of null object, ...
} catch (Exception e) {
throw new FAException("Ooops", "Something went wrong", e);
}
return i;
}
If you want to throw an exception when some criteria is met:
public static int exceptionTester(int i) throws FAException {
if (i == 0) {
throw new FAException("IllegalArgument", "arg can not be 0", null);
}
return i;
}
It is simply because you are not rethrowing the caught exception in the main method.
Even if you do this:
try {
if (i==0) {
throw new FAException("some status code", "some message", null);
}
} catch (Exception e) {
throw e; --> catching FAException and throwing it to the caller
// 'e' is of type FAException (though you caught it as Exception)
}
return i;
}
It should work, and you won't even hit the "return i" statement.
Otherwise (if no re-throwing, the catch statement will handle the exception and not the caller).
Rest, I agree with the above answer.
I have the following insert/update methods in my service:
#Override
public void insertEntity(Entity entity) {
try {
entityDao.insert(entityMapper.entityToEntityDO(entity));
} catch (DataIntegrityViolationException ex){
if(ex.getCause() instanceof SQLIntegrityConstraintViolationException) {
SQLIntegrityConstraintViolationException violationEx = (SQLIntegrityConstraintViolationException) ex.getCause();
if(violationEx.getErrorCode() == 1048 && "23000".equals(violationEx.getSQLState())) {
throw new FieldCannotBeNullException(violationEx.getMessage());
}
}
throw ex;
}
}
#Override
public void updateEntity(Entity entity) {
try {
entityDao.update(entityMapper.entityToEntityDO(entity));
} catch (DataIntegrityViolationException ex){
if(ex.getCause() instanceof SQLIntegrityConstraintViolationException) {
SQLIntegrityConstraintViolationException violationEx = (SQLIntegrityConstraintViolationException) ex.getCause();
if(violationEx.getErrorCode() == 1048 && "23000".equals(violationEx.getSQLState())) {
throw new FieldCannotBeNullException(violationEx.getMessage());
}
}
throw ex;
}
}
As you can see, the actual logic of insertEntity and updateEntity is very simple. In order to throw a custom Exception, I did some database error code check. Since the two methods all need this kind of checking, the code duplicated in both methods, which is obviously a code smell.
How can I eliminate this kind of code duplication?
Extract the common catch-block to a method which throws DataIntegrityViolationException.
You can create Interface like this:
public interface ConsumerWithException<T, V extends Exception> {
/**
* Performs this operation on the given argument.
*
* #param t the input argument
*/
void accept(T t) throws V;
}
Use it a private method like:
private void action(ConsumerWithException<Entity, DataIntegrityViolationException> doAction, Entity entity){
try {
doAction.accept(entity);
} catch (DataIntegrityViolationException ex){
if(ex.getCause() instanceof SQLIntegrityConstraintViolationException) {
SQLIntegrityConstraintViolationException violationEx = (SQLIntegrityConstraintViolationException) ex.getCause();
if(violationEx.getErrorCode() == 1048 && "23000".equals(violationEx.getSQLState())) {
throw new FieldCannotBeNullException(violationEx.getMessage());
}
}
throw ex;
}
}
You can put the code inside the catch block into a separate method.
Alternatively, You can catch Exception and write a handler method to handle the exceptions if in future you expect to handle multiple exceptions there.
You can declare your methods to throw the exception, then try/catch in one place where your methods are called. For example:
public void insertEntity(Entity entity) throws DataIntegrityViolationException {}
public void updateEntity(Entity entity) throws DataIntegrityViolationException {}
try {
insertEntity(entity);
updateEntity(entity);
catch (DataIntegrityViolationException e) {
// handle exception
}
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);
}
}