How to stop printing exception stack trace on Console?
Solution 1
Instead of adding java.lang.Exception
in your web.xml why won't you just try to add socket exception in web.xml itself like below
<error-page>
<exception-type>java.net.SocketException</exception-type>
<location>/exceptionHandler</location>
</error-page>
and just do nothing in your servlet
Or instead add a empty jsp file like
<error-page>
<exception-type>java.net.SocketException</exception-type>
<location>/error.jsp</location>
</error-page>
Solution 2
Here is what I done so war as work around.
Added one filter and hijack all the request and response.Catch the exception and check the type.
/**
* Hijacks all the http request and response here.
* Catch the SocketException and do not print
* If other exceptions print to console
* date : 9-18-2013
*
* @author Suresh Atta
*
*/
public class ExceptionHandler implements Filter {
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOException, ServletException {
try{
arg2.doFilter(arg0, arg1);
}catch(SocketException e ){
// Please don't print this to log.
}
}
}
And in web.xml
,filter mapping
<filter>
<filter-name>ExceptionHandler</filter-name>
<filter-class>com.nextenders.server.ExceptionHandler</filter-class>
</filter>
<filter-mapping>
<filter-name>ExceptionHandler</filter-name>
<dispatcher> REQUEST </dispatcher>
<url-pattern> /*</url-pattern>
</filter-mapping>
I'm not marking this as answer,since I'm not sure this is a standard way or not.Just a work around.
Solution 3
Use Jboss Custom Logging Handler to solve this problem.
If you don't want to log any SocketException
exception stack trace then just skip it while loggin into a file.
Steps to follow:
- A custom handler must inherit java.util.logging.Handler
Here is the code:
package com.custom.jboss.logging;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Date;
import java.util.logging.ErrorManager;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
public class SocketExceptionCustomLoggingHandler extends Handler {
private String logFile;
public BufferedWriter out = null;
public SocketExceptionCustomLoggingHandler() {
super();
logFile = "";
}
@Override
public void publish(LogRecord record) {
if (!initialize()) {
return;
}
if (isLoggable(record)) {
process(record);
}
}
private synchronized boolean initialize() {
if (out == null && logFile != null && !logFile.equals("")) {
FileWriter fstream = null;
try {
fstream = new FileWriter(logFile, true);
out = new BufferedWriter(fstream);
} catch (IOException e) {
reportError(e.getMessage(), e, ErrorManager.OPEN_FAILURE);
}
logToFile("Log file initialized. Logging to: " + logFile);
}
return true;
}
private void process(LogRecord logRecord) {
String log = getFormatter().format(logRecord);
if (log.indexOf("java.net.SocketException") == -1) {
logToFile(log);
}
}
private void logToFile(String text) {
try {
if (out != null) {
out.write((new Date()).toString() + "\t" + text + "\n");
out.flush();
}
} catch (IOException e) {
reportError(e.getMessage(), e, ErrorManager.WRITE_FAILURE);
}
}
@Override
public void flush() {
try {
if (out != null) {
out.flush();
}
} catch (IOException e) {
reportError(e.getMessage(), e, ErrorManager.FLUSH_FAILURE);
}
}
@Override
public void close() {
if (out != null) {
try {
out.close();
} catch (IOException e) {
reportError(e.getMessage(), e, ErrorManager.CLOSE_FAILURE);
}
}
}
public void setLogFile(String logFile) {
this.logFile = logFile;
}
}
The file is then packaged into a jar and placed in the modules directory.
i.e.
Jboss-7.1.1/modules/com/custom/jboss/loggers/main
together with a module.xml file. The contents of the module.xml should look like this.<?xml version="1.0" encoding="UTF-8"?> <module xmlns="urn:jboss:module:1.0" name="com.custom.jboss.loggers"> <resources> <resource-root path="SocketExceptionHandler.jar"/> <!-- Insert resources here --> </resources> <dependencies> <module name="org.jboss.logging"/> <module name="javax.api"/> </dependencies> </module>
Then modify the standalone.xml to support logging to the custom logger
<subsystem xmlns="urn:jboss:domain:logging:1.1"> ... <custom-handler name="SocketExceptionAppender" class="com.custom.jboss.logging.SocketExceptionCustomLoggingHandler" module="com.custom.jboss.loggers"> <level name="DEBUG"/> <formatter> <pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/> </formatter> <properties> <property name="logFile" value="d:\\temp\\logfile.txt"/> </properties> </custom-handler> ... <root-logger> <level name="INFO"/> <handlers> <handler name="SocketExceptionAppender"/> </handlers> </root-logger> </subsystem>
Add more handler in root-logger if needed such as FILE, CONSOLE etc.
- Now all the logs will be logged in your custom log file via this custom handler where we have skipped
SocketException
- We can make this class more generic passing properties from standalone.xml such as used to pass log file path.
Please let me know if there is any issue.
Solution 4
You probably will have to override fillInStackTrade method
public static class CustomException extends Exception {
@Override
public Throwable fillInStackTrace() {
return null;
}
}
Solution 5
As I understand it, exceptions are logged to the console when it is not caught before reaching the container. As such using a filter to catch unhandled exceptions makes sense.
Struts2 also has an exception 'interceptor' as its last interceptor, by default. See defaultStack. We need do override this interceptor if we need custom exception handling.
The only thing I would do additionally would be to log the exceptions (atleast to an errors-ignore.txt file) rather than completely skipping them.
Related videos on Youtube
Suresh Atta
Send a direct message My Fav questions How can a string be initialized using " "? The meaning of Java code (Object[])(Object[])arrayOfBytes[1] Where is .class defined in Java? (Is it a variable or what?)
Updated on March 14, 2020Comments
-
Suresh Atta about 4 years
I wrote a servlet to handle the exceptions occurring in my web app and mapped them in web.xml
<error-page> <exception-type>java.lang.Exception</exception-type> <location>/exceptionHandler</location> </error-page>
Here is what I have done in the Exception Handling servlet
service
method:@Override protected void service(HttpServletRequest req, HttpServletResponse arg1) throws ServletException, IOException { Object attribute = req.getAttribute("javax.servlet.error.exception"); if(attribute instanceof SocketException){ // don't do anything }else{ super.service(req, arg1); } }.
Problem:
The above approach is not working and the stack trace is printing to the console. This occurs when the user requests something and then closes their browser.
Question:
How do I stop printing the stacktrace to the JBoss console whenever a
SocketException
occurs?Reason for doing this:
I want to avoid seeing all of the log's
SocketException
s at the end of th day because I can't do anything with that information.-
Taylor Hx over 10 yearsIf you know why the exception is occurring, then shouldn't you be handling that exception according to your requirements when it occurs? A filter like you suggest would filter all occurrences of the exception, even when they occur for reasons other than those you expect.
-
Suresh Atta over 10 years@Daemon There is no way to handle that. I given the reason :). All I want to do is just escape that stacktrace in server logs.
-
Taylor Hx over 10 yearsAhh, I see. The exception is being held as an attribute of the
ServletRequest
, and isn't caught until request is processed. -
me_digvijay over 10 yearsI am not sure why you had to override the
service()
. I think this could have been done indoGet
anddoPost
methods. Also how do yourdoGet
anddoPost
methods look like. One more thing, why aren't you calling these two methods inside your service method? -
Sudarshan_SMD over 10 yearsAre you sure that using 'java.lang.Exception' for specifying exception-type works? Try using java.lang.Throwable, which should be used to specifying generic error handler. <exception-type>java.lang.Throwable</exception-type > As you want to handle SocketException, you might want to use something like this: <exception-type>java.net.SocketException</exception-type >
-
ericson over 10 yearsCould you attach the stack trace to your question? thanks.
-
Jorge Campos over 10 years@sᴜʀᴇsʜᴀᴛᴛᴀ As you are talking about jboss, what about add an appender to your
jboss-log4j.xml
? At $JBOSS_HOME/server/{profile}/default/conf -
Bimalesh Jha about 10 yearsAdding to previous comment by @JorgeCampos in log4j.xml check the package (Logger class) that logs the error and increase its Level Threshold to FATAL. This might work. Another option I would explore is to override the default HTTP connector of Tomcat and suppress/log
SocketException
at debug Level. -
Braj about 10 yearsPlease share the stack trace logged for
ScoketException
so that I can try to figure it out. -
Braj about 10 yearsHave you tries Jboss custom logging handler? Have a look at my answer and let me know if am I wrong as per your requirement.
-
-
Suresh Atta over 10 yearsTo write this I need to get the control over http response.That's stopping me to do this.
-
Matthias over 10 yearsI would do it differently. There is no reason to catch Exception in your code. I would just catch
SocketException
or at least rethrow the wrongly catched exceptions to allow other filters to react properly on those exceptions, not just swalling it and printing to the console. -
Suresh Atta over 10 years@Matthias Thanks for that spot. Editted with new code. This code posted long back and recently I changed the logic. Catching socket exception and doing nothing there.There is no way to handle that. I given the reason :). All I want to do is just escape that stack trace in server logs.
-
Matthias over 10 yearsYeah, I understand what you want to achieve and it certainly prevents the log from being scattered with misleading exceptions. The only thing you could do to "handle the SocketException" is to write a small message to your normal log (maybe on debug/info level) that the user aborted the request. This makes it easier to track sessions if you have some issues in production and have to follow a log file. I have that rule to log everything entering or leaving my application so I can track things.
-
Suresh Atta over 10 years@Matthias yes, yes. Now doing the same. Inside that catch block there is a little business logic to track things :)
-
Matthias over 10 yearsWonderful, then I believe your workaround is actually a neat solution.
-
Suresh Atta about 10 yearsThanks for the valuable response. Will try and get back to you.
-
oxfn about 10 yearsCan you provide an example, how
log4j
can prevent output of unhandled exception stack trace?