Exception throwing in smooks - exception

Is it possible to throw an Exception in the smooks configuration file.
Example if in an xml of order,
<order id="332">
<header>
<customer number="123">Joe</customer>
</header>
<order-items>
<order-item id='1'>
<product>1</product>
<quantity>2</quantity>
<price>8.80</price>
</order-item>
</order-items>
</order>
If the node <order-items> is not present then an exception should be thrown or an error should arise. Is there an option to do that in Smooks configuration file??

You could look at the validation cartridge. See the user guide.

Related

Mule Custom Exception Class not catching some exceptions

I have a Mule flow which obtains an oauth token from a service which may throw a fault. However the exception is not caught in the flow even though there is a catch exception strategy at the end. Can someone explain why the exception is not caught? When I post XML via SOAP UI using an invalid token to trigger an exception, the request gets to the flow, but the exception is not caught. Instead I get a stack trace indicating an invalid token. Here is the flow:
<flow name="order-query">
<http:listener config-ref="HTTP_config"
path="order/request" doc:name="HTTP" />
<flow-ref name="oauth-token-service">
<cxf:jaxws-service doc:name="SPOP SOAP"
serviceClass="o.x.p.SpopWS">
<cxf:inInterceptors>
<spring:ref bean="HeaderInInterceptor" />
</cxf:inInterceptors>
<cxf:outInterceptors>
<spring:ref bean="faultOutInterceptor" />
<spring:ref bean="headerOutInterceptor" />
</cxf:outInterceptors>
<cxf:outFaultInterceptors>
<spring:ref bean="OutSoapFaultInterceptor" />
</cxf:outFaultInterceptors>
</cxf:jaxws-service>
<scripting:transformer>
<scripting:script engine="python">
...
</scripting:script>
<scripting:transformer>
<catch-exception-strategy>
<logger level="INFO" message=" Should be handled here #[payload]"/>
</catch-exception-strategy>
</flow>
are you sure the exception is not catched? the default behavior of catch-exception-strategy is to log the catched exception. This is the reason why you see the stack trace in logs.
for mule 3.8 and above: you can disable/enable this behavior either with a checkbox (Log Exceptions):
or in XML (logException=false):
<catch-exception-strategy logException="false" doc:name="Catch Exception Strategy">
<logger level="INFO" doc:name="Logger"/>
</catch-exception-strategy>
for mule 3.7: take a look here: https://stackoverflow.com/a/42181054/804521

How to create custom exception handler class in Struts2 [duplicate]

This question already has an answer here:
Struts2 Exception handling usage?
(1 answer)
Closed 6 years ago.
How to create custom exception handler class in Struts2? I have tried adding the exception code in execute() but failed.
I hope that this guidelines will be usefull for your question, since it looks a little too broad, so if you have a specific requirement just edit your question. First of all I suggest you to read the official documentation in order to retrieve information about the Exception handling, Exception configuration and Exception Interceptor.
Now, I try to be more detailed as I can two explain how you can handle the exceptions in Struts2:
Global exception handling: everytime your application throws an exception, Struts2 will handle the result with the <global-results> and <global-exception-mappings> tags in struts.xml file.
Action exception handling: everytime your specific action throws an exception, Struts2 will handle the result <exception-mapping> tag inside a <action> tag
Global exception handling
Using the Struts 2 framework you can specify in the struts.xml how the framework should handle uncaught exceptions. The handling logic can apply to all actions (global exception handling) or to a specific action. Let's first discuss how to enable global exception handling.
To enable global exception handling you need to add two nodes to struts.xml: global-exception-mapping and global-results. For example examine struts.xml from the exception_handling project.
<global-results>
<result name="securityerror">/securityerror.jsp</result>
<result name="error">/error.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="org.apache.struts.register.exceptions.SecurityBreachException" result="securityerror" />
<exception-mapping exception="java.lang.Exception" result="error" />
</global-exception-mappings>
Now when a SecurityBreachException is thrown, the securityerror.jsp will be loaded. In my opinion global exception are very usefull for generic errors. For example you can create an ApplicationException view with a form used to send to your assistance the stack trace of the problem.
Action exception handling
If you need to handle an exception in a specific way for a certain action you can use the exception-mapping node within the action node.
<action name="actionspecificexception" class="org.apache.struts.register.action.Register" method="throwSecurityException">
<exception-mapping exception="org.apache.struts.register.exceptions.SecurityBreachException" result="login" />
<result>/register.jsp</result>
<result name="login">/login.jsp</result>
</action>
In this example when throwSecurityException method of the Register action throws a SecurityBreachException it returns a LOGIN result and the login.jsp is loaded. I've used this kind of solution for actions that may throw errors after a validation (for example to execute CRUD operations in my database).
Custom error jsp
By default, the ExceptionMappingInterceptor adds the following values to the Value Stack:
exception : The exception object itself
exceptionStack : The value from the stack trace
You can use them to create a custom jsp that prints the error occurred and the stacktrace. Here you have an example:
<h2>An unexpected error has occurred</h2>
<p>
Please report this error to your system administrator
or appropriate technical support personnel.
Thank you for your cooperation.
</p>
<hr/>
<h3>Error Message</h3>
<s:actionerror/>
<p>
<s:property value="%{exception.message}"/>
</p>
<hr/>
<h3>Technical Details</h3>
<p>
<s:property value="%{exceptionStack}"/>
</p>
Logs
I think that also the LoggingExceptions paragraph will be usefull.

Why the Exception raised from my Interceptor is not caught by <global-exception-mappings>?

I have a custom Interceptor, from which I throw an Exception;
The Action(s) running that Interceptor is managed by Convention plugin;
The Exception raised by the Interceptor is globally defined in struts.xml for the package the Action is running into.
RESULT: the exception mapping is ignored and I get the
Struts Problem Report
Struts has detected an unhandled exception:
...
Stacktraces
java.lang.IllegalArgumentException: my message
I guess I'm just missing something stupid... we've already discussed of this in a similar question, but it's still not clear if it can or can't work this way:
struts.xml
<package name="my-package" namespace="my" extends="struts-default">
<interceptors>
<interceptor name="myInterceptor" class="foo.bar.MyInterceptor"/>
<interceptor-stack name="myStack">
<interceptor-ref name="myInterceptor"/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="myStack"/>
<global-results>
<result name="input">/WEB-INF/content/my-input.jsp</result>
<result name="error">/WEB-INF/content/my-error.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="java.lang.IllegalArgumentException"
result="error" />
<exception-mapping exception="java.lang.Exception" result="error" />
</global-exception-mappings>
</package>
Action
#ParentPackage("my-package")
#Namespace("/my/blabla/yadayada")
public class MyAction extends MyBaseAction {
}
Interceptor
#Override
public String intercept(ActionInvocation actionInvocation) throws Exception {
// ....
if (somethingWrong) {
throw new IllegalArgumentException("All work and no play makes Jack a dull boy");
}
}
I've also tried defining global result / global exception mapping in the abstract BaseAction, or in the physical real Action itself, but they're ignored too.
Any idea on what to add / remove / change in order to make it work as it should ? This is not esoteric stuff, this is basic :|
The main candidate for exception mapping feature is actions throwing an exceptions.
Docs:
Exception mappings is a powerful feature for dealing with an Action class that throws an Exception. The core idea is that an Exception thrown during the Action method can be automatically caught and mapped to a predefined Result.
But exceptions thrown from interceptors can be also handled by exception interceptor. In order to catch other interceptors exceptions exception interceptor should be defined as the first interceptor in the stack.
From the ExceptionMappingInterceptor javadoc:
It is recommended that you make this interceptor the first interceptor on the stack, ensuring that it has full access to catch any exception, even those caused by other interceptors.

Mule always use the default exception handler

I can not catch a basic org.mule exception triggered by a Poller component, Mule is still using the default mechanism (tried both Global or Local)
In case the below exception is thrown I would like to print something personal in the Log it self just for testing purpose, further enhancements will occur once this is working properly.
Message : Failed to move file "C:\Users\Administrator\Desktop\shared_folder\12131551.XML" to "C:\Users\Administrator\Desktop\archive\backup\12131551.XML.backup". The file might already exist.
Code : MULE_ERROR-3
Exception stack is:
1. Failed to move file "C:\Users\Administrator\Desktop\shared_folder\12131551.XML" to "C:\Users\Administrator\Desktop\archive\backup\12131551.XML.backup". The file might already exist. (org.mule.api.DefaultMuleException)
org.mule.transport.file.FileMessageReceiver:553 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/DefaultMuleException.html)
Root Exception stack trace:
org.mule.api.DefaultMuleException: Failed to move file "C:\Users\Administrator\Desktop\shared_folder\12131551.XML" to "C:\Users\Administrator\Desktop\archive\backup\12131551.XML.backup". The file might already exist.
at org.mule.transport.file.FileMessageReceiver.moveAndDelete(FileMessageReceiver.java:553)
at org.mule.transport.file.FileMessageReceiver.access$400(FileMessageReceiver.java:62)
at org.mule.transport.file.FileMessageReceiver$2.process(FileMessageReceiver.java:414)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
This is my PoC
<file:connector name="XML_poller" autoDelete="false" streaming="false" validateConnections="true" pollingFrequency="5000" doc:name="File"/>
<file:connector name="output" doc:name="File" autoDelete="false" streaming="false" validateConnections="true"/>
<flow name="exceptionStrategyExample" doc:name="exceptionStrategyExample">
<file:inbound-endpoint connector-ref="XML_poller" path="C:\Users\Administrator\Desktop\shared_folder" moveToDirectory="C:\Users\Administrator\Desktop\archive\backup"
moveToPattern="#[header:originalFilename].backup" doc:name="Poller" responseTimeout="10000">
<file:filename-wildcard-filter pattern="*.xml" caseSensitive="false"/>
</file:inbound-endpoint>
<http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" method="POST" doc:name="HTTP"/>
<choice-exception-strategy>
<rollback-exception-strategy
when="exception.causedBy(java.lang.IllegalStateException)"
maxRedeliveryAttempts="3">
<logger message="Retrying shipping cost calc." level="WARN" />
<on-redelivery-attempts-exceeded>
<logger message="Too many retries shipping cost calc."
level="WARN" />
<set-payload value="Error: #[exception.summaryMessage]"/>
</on-redelivery-attempts-exceeded>
</rollback-exception-strategy>
<catch-exception-strategy doc:name="Catch Exception Strategy" when="exception.causedBy(org.mule.*)">
<logger message="************TEST***************" level="INFO" doc:name="Logger"/>
</catch-exception-strategy>
</choice-exception-strategy>
</flow>
It is simply not doing anything.... Any hints ?
I think this is a case of a System Exception, where no message is created that could be caught by the exception handling components (see Mule docs for System vs Messaging exceptions). You could try either writing a custom message receiver overriding the processFile method (see this post for inspiration), or check the existence of duplicate files manually and use a separate file:outbound-endpoint for writing the file.
I have found a workaround. Insert a processor chain element before file connector and put a dummy set-payload. In this way you will always create a message and then it ll not use DefaultExceptionStrategy for handling the errors.

How to prevent logback from outputting its own status at the start of every log when using a layout

This seems like a carelessness error, but I can't seem to find the cause. Logging with logback/slf4j (most recent version slf4j-api-1.6.1, logback core/classic 0.9.24). Simplest log configuration for testing is:
<configuration>
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<!-- DONT USE THIS FORMATTER FOR LIVE LOGGING THE %L LINE NUMBER OUTPUTTER IS SLOW -->
<pattern>%le %-1r [%c{1}:%L] %m%n</pattern>
</layout>
</appender>
<root level="DEBUG">
<appender-ref ref="stdout" />
</root>
</configuration>
Every log setup starts with logback's internal status lines:
11:21:27,825 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
11:21:27,826 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback-test.xml] at [file:.../logback-test.xml]
11:21:28,116 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
11:21:28,124 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
11:21:28,129 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [stdout]
11:21:28,180 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Pushing component [layout] on top of the object stack.
11:21:28,206 |-WARN in ch.qos.logback.core.ConsoleAppender[stdout] - This appender no longer admits a layout as a sub-component, set an encoder instead.
11:21:28,206 |-WARN in ch.qos.logback.core.ConsoleAppender[stdout] - To ensure compatibility, wrapping your layout in LayoutWrappingEncoder.
11:21:28,206 |-WARN in ch.qos.logback.core.ConsoleAppender[stdout] - See also http://logback.qos.ch/codes.html#layoutInsteadOfEncoder for details
11:21:28,207 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to DEBUG
11:21:28,207 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [stdout] to Logger[ROOT]
which is, according to the docs, the format logback uses for default. It then finishes reading the config (which is set up to output a different format) and continues with the properly formatted output. There's a config parameter <configuration debug="false"> which does not affect this.
Anyone know how to shut this off?
If you set the debug attribute of the configuration element to true, you will get all status information to the console. If this is your problem, just set it to false or remove it.
If you have any configuration problems of level WARN or above, you will also get all status information logged to the console (including messages of level INFO). The best solution to this problem is to fix the problem (in your case replace the <layout> element with an <encoder> element).
If you for some reason cannot fix the problem, but want to remove the status-information from the console, you can instead configure an alternative StatusListener. Use the NopStatusListener to completely remove the status-information:
<configuration>
<statusListener class="ch.qos.logback.core.status.NopStatusListener" />
<!-- etc -->
</configuration>
As described in the docs, if warnings or errors occur during the parsing of the configuration file, logback will automatically print status data on the console.
Follow http://logback.qos.ch/codes.html#layoutInsteadOfEncoder i.e.
the link mentioned by logback in its warning message. Once you follow the steps mentioned therein, that is, if you replace <layout> element with <encoder>, logback will stop printing messages on the console.
Ceki answer is correct:
(...)if warnings or errors occur during the parsing of the configuration file, logback will automatically print status data on the console.
Once you get it right, there won't be any pollution in the first lines of your log anymore.
As of March 2015, in Logback 1.1.2, you need to use <encoder> sub-component - <layout> is now deprecated and if use it, error messages will appear. You cannot control this, it´s Logback default behavior.
Some internal classes have been renamed too, and even the examples in their manual page are outdated!
Here is the code snippet from their Errors Code Help page, which has the correct way to config the logger. This fixed the issue completely in my project.
http://logback.qos.ch/codes.html#layoutInsteadOfEncoder
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>testFile.log</file>
...
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%msg%n</pattern>
</encoder>
</appender>
I had the same problem i added this line
<!-- Stop output INFO at start -->
<statusListener class="ch.qos.logback.core.status.NopStatusListener" />
in the logback and it succefully worked
I realized Steve found the fix but he didn't mention it on the thread. In case if any other person hit the same issue here is the fix.
Replace "<layout>" elements with "<encoder>..</encoder>"
The culprit is:
<layout class="ch.qos.logback.classic.PatternLayout">
I prefer to use status listener in order to switch off own logback logs:
<configuration>
<statusListener class="ch.qos.logback.core.status.NopStatusListener" />
...
</configuration>
But as was mentioned NopStatusListener also prevents showing warning and errors. So you can write your custom status listener and change log level for it manually:
package com.your.package;
import ch.qos.logback.core.status.OnConsoleStatusListener;
import ch.qos.logback.core.status.Status;
import java.util.List;
public class PrintOnlyWarningLogbackStatusListener extends OnConsoleStatusListener {
private static final int LOG_LEVEL = Status.WARN;
#Override
public void addStatusEvent(Status status) {
if (status.getLevel() == LOG_LEVEL) {
super.addStatusEvent(status);
}
}
#Override
public void start() {
final List<Status> statuses = context.getStatusManager().getCopyOfStatusList();
for (Status status : statuses) {
if (status.getLevel() == LOG_LEVEL) {
super.start();
}
}
}
}
Then use it in your logback.xml file:
<configuration>
<statusListener class="com.your.package.PrintOnlyWarningLogbackStatusListener" />
...
</configuration>
Struggled with the same problem myself i.e. there were a bunch of lines logged right at the beginning which were not related to my code. Here is how I fixed it.
<configuration debug="false">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level
%logger{36} - %msg%n</pattern> </encoder> -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} %-5level %logger{10} - %msg%n</pattern>
</encoder>
</appender>
<root level="error">
<appender-ref ref="STDOUT" />
</root>
<logger name="fun.n.games" level="DEBUG" />
This is running with the following entry in the pom.xml
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
This seems to be Fixed in 0.9.29. Just made several tests. No Joran INFO anymore. I guess this is the fixing commit.
I've tried everything and nothing worked for me. My problem was due to multiple logback.xml files in my classpath. This is the common case in multi modular projects.
When there is only one logback.xml file in classpath, there is no ambiguity and the problem is solved.
Using the logback.groovy: statusListener(NopStatusListener) (in the src/test/resources/logback.groovy) works.
(A valid use case is e.g. if working with ANT in Eclipse, using logback logging, groovy classes and unit tests where the unit tests take the src/test/resources/logback.groovy, but will also see the src/main/resources/logback.groovy (or similar) you cannot exclude (if ANT's classpath is said to use the projects classpath).)
Just for people landing here because of the status messages logged by ch.qos.logback.access.tomcat.LogbackValve#LogbackValve (recent versions). Just set the quiet flag:
var v = new LogbackValve();
v.setQuiet(true); // disable status messages!
v.setFilename("logback-access.xml");
See also the documentation for XML configuration.