I\'m new to java and I\'m not that familiar with the formatting rules used by an error stack trace when it is thrown and subsequently displayed to an end-user of my web appl
You shouldn't show any of that gobbledygook to your users. It's meaningless to most of them and doesn't help you. As you suspect, it also exposes internals of your implementation that may suggest vulnerabilities that a malicious user might be able to use.
Instead, you should catch exceptions, log them, and show a more comprehensible error message to your users. You can use getMessage()
to extract the message part of an exception. If the exception has no message, then show something like "no details available".
UPDATE:
I have some comments based on the question update. First, I would totally insulate the user from any of the internals of your system, both to be kind to the user and for security. (For instance, even knowing that you are using the java.sql package may suggest vulnerabilities to a clever hacker.) So do not use the exception message, the first line of the stack trace, or anything like that when displaying anything to the user.
Second, you should be mapping all errors from the exception level (at which they are experienced in your code) to messages that are at the right level of abstraction for the user. The proper way to do that would depend on the internals of your system and what the user might have been trying to do when the exception was raised. This might mean structuring your system into layers such that each layer that catches an exception translates it into an exception at a higher layer of abstraction. A Java exception can wrap another exceptions (the cause). For instance:
public boolean copyFile(File source, File destination) throws CopyException {
try {
// lots of code
return true;
} catch (IOException e) {
throw new CopyException("File copy failed", e);
}
}
Then this could be used at a higher level in a User class:
public boolean shareFile(File source, User otherUser) throws ShareException {
if (otherUser.hasBlocked(this) {
throw new ShareException("You cannot share with that user.");
}
try {
return copyFile(source, otherUser.getSharedFileDestination(source));
} catch (CopyException e) {
throw new ShareException("Sharing failed due to an internal error", e);
}
}
(I hope it's clear that the above code is meant to illustrate the idea of converting exceptions to higher levels of abstraction, not as a suggestion for code that you should use in your system.)
The reason that you want to handle things like this (instead of somehow massaging the message and/or stack trace) is that an exception (for instance an IOException with message "permission denied") may mean totally different things to the user (and to your system) in different contexts.