With Struts2, you can define global exception mappings for specific Exception
types. If you define one for java.lang.Exception it acts as a catch-all for any exception not mapped elsewhere:
<global-exception-mappings>
<exception-mapping exception="com.example.MyException result="myError" />
<exception-mapping exception="java.lang.Exception" result="error" />
</global-exception-mappings>
<global-results>
<result name="myError">/myError.jsp</result>
<result name="error">/error.jsp</result>
</global-results>
In your error JSPs (*), you can then log them with log4j and give your users a nice "Something went wrong" error page without confronting them with confusing stacktraces.
(*) better: An error action where you can log the exception and only then let Struts render a JSP where you tell the user that something went wrong. No need to clutter JSPs with logging code.
About modifying all your code:
Don't blindly add catch blocks all over your code -- if some piece of code can't handle an exception, just let it propagate (adding a throws
clause on the method signature if necessaty). At certain levels in the stack, consider wrapping the thrown Exception and adding some information to help identifying the cause and rethrow it:
catch (IllegalArgumentException ex) {
// Always pass the original exception along, never just the message.
// It's much easier to find the root cause that way.
throw new UpdateException("Failed to parse foo object: " + foo, ex);
}
Also, resist the temptation of emtpy catch blocks. They swallow the exception and you may never find out that something or what might be going wrong in your application. Log all exceptions unless you're very sure you'll never be interested in them.