I have my Exception handler, which is used for enterprise library exception handling.
This handler contains method HandleException:
public Exception HandleException(Exception exception, Guid handlingInstanceId)
{
Exception wrap = new Exception();
wrap.StackTrace = exception.StackTrace;
return wrap;
}
When I try to assign received exception.StackTrace property to my variable wrap, I get Error:
property or indexer 'System.Exception.StackTrace' cannot be assigned to -- it is read only
How I can assign it to my variable?
This is typically what I've seen.
public Exception HandleException(Exception exception, Guid handlingInstanceId)
{
//Do something with the Exception.
return exception;
}
or
public Exception HandleException(Exception exception, Guid handlingInstanceId)
{
ApplicationException appEx = new ApplicationException(exception.Message, exception);
return appEx ;
}
Related
I'm studying interceptors and decorator and when experimenting with it I've encountered the problem that if I throw a checked exception from an interceptor, the EJBContainer wraps it as an EJBException, instead what I would like to show to the client is my custom exception.
Assume that I've one simple method and one interceptor that check if the parameters are valid like so:
#Interceptor
public class TestIntercepor {
#AroundInvoke
public Object test(InvocationContext invCtx) throws Exception{
try {
//check parameters...
return invCtx.proceed();
} catch (CustomException ex) {
throw new CustomException();
} catch (Exception ex) {
throw new Exception();
}
}
}
The exception that I want to throw if something's off is CustomException:
public class CustomException extends Exception {
public CustomException() {
super("ERROR! Input fields not valid");
}
}
now I've noticed in my SOAP Fault message that the exception throwed is an EJBException. I did some research and found out that the EJB Container wraps all the SystemException throwed, so I'm assuming that my CustomException throwed by the interceptor is treated as an uncecked exception for some reason, while if I throw the same exception from the business method, the client see exactly the right exception in the message.
I've even tryed to add the #ApplicationException annotation in my CustomException class for be completely sure that my Exception has to be treated as an ApplicationException instead of a SystemException, but it doesn't seem to be working.
There's something I'm missing?
I've found out that if your custom exception extends RuntimeException instead of Exception it works. Seems like that the #ApplicationException work only if the exception is a System Exception like RuntimeException and not if extends normal Exception.
#ApplicationException(rollback = true)
public class CustomException extends RuntimeException {
public CustomException() {
super("ERROR! Input fields not valid");
}
}
i have a restcontroller with following Code
#RequestMapping(method = RequestMethod.POST, value = "/student")
public void addTopic(#RequestBody Student student) {
student.setPassword(bCryptPasswordEncoder.encode(student.getPassword()));
studentService.addStudent(student);
}
but if the json data doesn't match the Student object, or is wrong formatted an com.fasterxml.jackson.core.JsonParseException: Unexpected character ('"' (code 34)) ist thrown.
what is the best practice to prevent that
I've found that I need to catch JsonProcessingException (which JsonParseException extends from) in the #ExceptionHandler rather than JsonParseException
#ControllerAdvice
public class FeatureToggleControllerAdvice {
#ExceptionHandler(JsonProcessingException.class)
public ResponseEntity<JSONAPIDocument> handleJsonParseException(JsonProcessingException ex) {
final Error error = new Error();
error.setId(UUID.randomUUID().toString());
error.setStatus(HttpStatus.BAD_REQUEST.toString());
error.setTitle(ex.getMessage());
return new ResponseEntity<>(JSONAPIDocument
.createErrorDocument(Collections.singleton(error)), HttpStatus.NOT_FOUND);
}
}
Using JsonParseException in the above sample and nothing is caught, but using JsonProcessingException works as expected.
Use Spring ExceptionHandler to do that
You could specify an ExceptionHandler based on Exception types and also apply the error codes you want to use.
#ExceptionHandler(JsonParseException.class)
public JacksonExceptionHandler {
public ResponseEntity<String> handleError(final Exception exception) {
HttpStatus status = HttpStatus.BAD_REQUEST;
if (exception != null) {
LOGGER.warn("Responding with status code {} and exception message {}", status, exception.getMessage());
return new ResponseEntity<>(exception.getMessage(), status);
}
}
Furthermore you could make use of javax.validation to validate the entity you receive and then Spring Boot will do all the validation automagically. Just add #Valid to the body.
I am testing a method with an expected exception.
I also need to verify that some code was called (on a mocked object) after the exception is thrown, but verification is being ignored.
Here is the code:
public class ExceptionHandler {
#Autowired
private Sender sender;
public void handle(Exception exception) throws Exception {
if (!SomeException.class.isAssignableFrom(exception.getClass())) {
sender.sendMessage(ExceptionUtils.getStackTrace(exception));
}
throw exception;
}
}
Here is the test code:
#Mock
private Sender sender;
#InjectMocks
private ExceptionHandler handler;
#Test
public void testHandler() throws Exception {
SomeException someException = new SomeException();
try {
handler.handle(someException);
} catch (SomeException thrownResult) {
assertEquals(someException, thrownResult);
}
verify(sender, times(1)).sendMessage(Mockito.anyString());
}
I also need to verify that some code was called (on a mocked object)
after the exception is thrown, but verification is being ignored.
This is not true, this line is actually executed:
verify(sender, times(1)).sendMessage(Mockito.anyString());
But it fails verification with this error:
Wanted but not invoked: sender.sendMessage();
<...>
Actually, there were zero interactions with this mock.
As expected, that method was never invoked, because condition !SomeException.class.isAssignableFrom(exception.getClass()) was not satisfied - you invoke handler.handle with instance of SomeException.
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
}
}
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.