Get exception information in mule catch exception strategy - exception

I am using catch exception strategy in my mule flow(v3.7.3).If an exception is thrown in my flow .I want to retrieve the exception in catch exception strategy.
Mule exception flow:
<choice-exception-strategy
doc:name="Choice Exception Strategy">
<catch-exception-strategy
when="exception.causedBy(com.nc.exception.NcException)"
doc:name="Notification Center Exception Strategy">
<custom-transformer
class="com.zoto.nc.transformer.json.ExceptionTransformer" doc:name="Exception Transformer">
</custom-transformer>
</catch-exception-strategy>
</choice-exception-strategy>
In my ExceptionTransformer.java i want to handle the exception and get the exception object(to print the stacktrace)
ExceptionTransformer.java
public class ExceptionTransformer extends AbstractMessageTransformer {
private static org.apache.log4j.Logger LOG = Logger.getLogger(ExceptionTransformer.class);
#Override
public Object transformMessage(MuleMessage message, String outputEncoding) throws TransformerException {
// Need caught exception trace here.
try {
LOG.info("Initiating Transformer for Exception Response" + message.getPayloadAsString());
} catch (Exception e2) {
e2.printStackTrace();
}
LOG.info("Request landed at :" + new Date());
return message.getPayload();
}
Is there a way to get the exception stacktrace in the ExceptionTrasformer class?

What you should do is ask the MuleMessage for it's ExceptionPayload, which has the thrown exception where you can get the trace. That is message.getExceptionPayload().

Related

EJB wraps my customExceptions throwed from interceptors

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");
}
}

Handling CompressorException in Java8 Streams

I have a static method for reading .bz2 files, it throws checked IOException and org.apache.commons.compress.compressors.CompressorException. The function signature is:
private static MyClass readFile(String fileName) throws IOException, CompressorException{
//…
}
Trying to use this method outright with Java8 streams gets compile time errors in Intellij;
unhandled exceptions: java.io.IOException, org.apache.commons.compress.compressors.CompressorException
So following advice from here, among others, I’ve tried the following but am stuck on how to handle the CompressorException object. Following it’s ctor I’ve tried as below but Intellij still complains the CompressorException is unhandled:
files.stream().forEach(i -> {
try{
readFile(i);
} catch (IOException e){
throw new RuntimeException(e);
} catch (Throwable ex){
throw new CompressorException("compressorException", ex);//error!!!
}
});
Thanks
As #JB Nizet mentioned in the comment, you cannot throw any Exception from the lambda function inside foreach function.
You need to replace your current implementation:
catch (Throwable ex){
throw new CompressorException("compressorException", ex);//error!!!
}
to either the following or not throw the RuntimeException at all.
catch (Throwable ex){
throw new RuntimeException("compressorException", ex);
}
The reason for the above behaviour is that the Stream.foreach() method has the following signature and doesn't throw any exception as part of the signature.
void forEachOrdered(Consumer<? super T> action)

How to Handle exceptions occured in jdbc code in servlet class [duplicate]

I am writing the servlet , in case of exception I am redirecting to my customized error page for that i have done like this.
In web.xml
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/WEB-INF/jsp/ErrorPage.jsp</location>
</error-page>
In Servlet,
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
try{
//Here is all code stuff
Throw new Exception();
}catch(Exception e){
e1.printStackTrace();
}
But here ErrorPage.jsp is not displaying , where I am going wrong can anyone explain me?
You're catching the exception, and only printing the stacktrace inside, so the error-page doesn't take affect, remove the try-catch or re-throw and it will work. In addition, you have some syntax errors. Try something like
try{
//Here is all code stuff
throw new Exception();
}catch(Exception e){
e.printStackTrace();
throw new ServletException();
}
The problem is that you catch the Exception and therefore no Exception will leave your doPost() method. You will only be redirected error page if an Exception matching the <exception-type> (either identical or a subclass of it) leaves your doPost() method.
You should rethrow the Exception bundled in a RuntimeException for example:
} catch(Exception e) {
e1.printStackTrace();
throw new RuntimeException(e);
}
Unfortunately if we're talking about a general Exception you can't just not catch it because doPost() is declared to only throw instances of ServletException or IOException. You are allowed not to catch those, but java.lang.Exception must be caught.
You have handled the Exception in your doPost() using ,
try{
//Here is all code stuff
Throw new Exception();
}catch(Exception e){
e1.printStackTrace();
}
try and catch blocks. so the errorPage.jsp will not be invoked. <error-page> is invoked for unhandled exceptions
A nice example tutorial Exception Handling
Read for more info Best practice error handling in JSP Servlets

Exception Handling in java to show user the catch error message from the nested method calls

I have doubt in Exception handling in java,when the exception is thrown in the called method, how to show the catch error in the calling method
Yes, it is possible to catch exception inside called method, and then re-throw same exception back to caller method.
public String readFirstLineFromFile(String path) throws IOException {
try {
BufferedReader br = new BufferedReader( new FileReader (path));
StringBuilder lines = new StringBuilder();
String line;
while((line = br.readLine()) != null) {
System.out.println("REading file..." + line);
lines.append(line);
}
return lines.toString();
} catch(IOException ex) {
System.out.println("Exception in called method.." + ex);
throw ex;
}
}
Note: It is not possible if you are using try with resources, and exception occurred inside resources itself like opening of file, or file not found. In that case exception will be directly thrown back to caller.

Java Unit test for Exception

public Document query(String uri) throws IOException, IllegalArgumentException
{
final HttpGet httpget = new HttpGet(uri);
final HttpResponse response = httpclient.execute(httpget);
final HttpEntity entity = response.getEntity();
Document doc = null;
try
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
doc = builder.parse(entity.getContent());
}
catch (SAXException e)
{
LOGGER.error(e);
throw new IllegalArgumentException("parse error" + e);
}
catch (ParserConfigurationException e)
{
LOGGER.error(e);
throw new IllegalArgumentException("parameter factor is invalid: " + e);
}
catch (IllegalStateException e)
{
LOGGER.error(e);
throw new IllegalArgumentException("null entity contetents" + e);
}
return doc;
}
#Test(expected = IllegalArgumentException.class)
public void testQuery_ParseExceptionThrown() throws Exception
{
String uri ="some uri";
EasyMock.expect(httpClient.execute(EasyMock.isA(HttpGet.class))).andReturn(mockResponse);
EasyMock.expect(mockResponse.getEntity()).andReturn(mockEntity);
EasyMock.expect(mockEntity.getContent()).andReturn(new ByteArrayInputStream(REPSONSE_EXAMPLE.getBytes()));
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
EasyMock.expect(builder.parse(EasyMock.isA(InputStream.class))).andThrow(
new IllegalArgumentException("expected"));
EasyMock.replay();
class.query(uri);
}
error:
java.lang.IllegalStateException: calling verify is not allowed in record state
at org.easymock.internal.MocksControl.verify(MocksControl.java:181)
at org.powermock.api.easymock.internal.invocationcontrol.EasyMockMethodInvocationControl.verify(EasyMockMethodInvocationControl.java:120)
at org.powermock.api.easymock.PowerMock.verify(PowerMock.java:1650)
at org.powermock.api.easymock.PowerMock.verifyAll(PowerMock.java:1586)
at com.amazon.ams.test.AbstractUnitTest.verifyMocks(AbstractUnitTest.java:78)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.internal.runners.MethodRoadie.runAfters(MethodRoadie.java:145)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:99)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:296)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:112)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:73)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:284)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:84)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:209)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:148)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:122)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:102)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:42)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
I keep getting some errors like
java.lang.AssertionError: Expected exception: org.xml.sax.SAXException
java.lang.IllegalStateException: calling verify is not allowed in record state
There are 3 exceptions I need to write Junit test to get into the exception. Does anyone know how to use powermock or easymock class to write the unit test for it?
If you have a mock for the builder using easymock you can throw Exceptions instead of return values:
EasyMock.expect(builder.parse(myContent)).andThrow( myException);
Where myException is an Exception instance you want to throw (created by new MyException(...));
EDIT: example test code:
#Test
public void parseThrowsIllegalStateException(){
//... creating mock factory, builder and entity not shown
//create new Exception to be thrown
IllegalStateException expectedException = new IllegalStateException("expected");
EasyMock.expect(mockBuilder.parse(mockContent).andThrow(expectedException);
EasyMock.replay(...);
//exercise your system under test which tries to parse the entity's Content
//...
}
EDIT 2: now that you posted your actual test code I think the problem might be these lines:
EasyMock.expect(mockEntity.getContent()).andReturn(new ByteArrayInputStream(REPSONSE_EXAMPLE.getBytes()));
...
EasyMock.expect(builder.parse(new ByteArrayInputStream(malformed_XML.getBytes()))).andThrow(new SAXException("expected"));
I don't think ByteArrayInputStream overrides equals() so it is using Object.equals(). The ByteArrayInputStreams won't be equal so EasyMock will never throw the Exception
I would change the builder.parse() expectation to:
EasyMock.expect(builder.parse(EasyMock.isA(InputStream.class))).andThrow(new SAXException("expected"));
Which will throw when parse is called no matter what the inputStream is.
As a side note, your error message the mentioned "calling verify is not allowed in record state" but I don't see any calls to verify() or verifyAll() anywhere.