Should you report the message text of exceptions? - java

Consider some code that can throw a checked exception (an exception of type Exception). Your code catches the exception, of course. You don't just swallow the exception either, your code reports it in some way to the user through your user interface. In a log file, perhaps, or using a GUI pop-up.
Should the text you report to the user include the message text of the exception. That is, the text provided by Throwable.getMessage() or Throwable.getLocalizedMessage()?
I think not, but it seems many disagree with me. So what have I got wrong? My argument is as follows.
The message was created when the exception was thrown. It therefore at best can provide only very low level information, which can be inappropriate for reporting to a user.
Philosophically, using the message seems to me against the whole point of exceptions, which is to separate the detection and initiation of error handling (the throw part) from completion of handling and reporting (the catch part). Using the message means the message must be good for reporting, which moves responsibility for reporting to the location that should be responsible for only detection and initiation. That is, I'd argue that the getMessage() part of the design of Throwable was a mistake.
The message is not localised. Despite its name, getLocalizedMessage() is not much good because you might not know what locale you want to use until you catch the exception (is the report to go to a system log read by your English system administrators, or is it to pop up in a window for the French user of the GUI?).
I hear that Java 7 has a much improved exception hierarchy for IOException, enabling you to handle different kinds of I/O erors in diffferent catch clauses, making the getMessage() text less important. That implies even the Java designers are somewhat uncomfortable with getMessage().
I'm not asking whether reporting the stack-trace is useful. A stack-trace is only ever going to be useful for an exception that suggests a bug. That is, for an unchecked exception. I think in such circumstances providing the low-level detail of the exception message is not just useful but mandatory. But my question deals with checked exceptions, such as file-not-found.
And I am not asking about the "best practice" for the message text.

If you are presenting an error condition to the user, it should probably be a user-friendly message. Exceptions contain technical details that the user should not/does not need to know.
In some situations it could be a security concern to present stacktrace information, so the user should never be shown stack traces.
If you are displaying error messages to the user, there is some point where you consciously make the decision to show a popup, or add a message to a log window. At that point you can translate any exception into a more user friendly message. Note that you might need more information than the default Exception types provide, so you can/should probably create you own Exception types that contain all the information you need to present all the data you need to the user.

No, exceptions shouldn't be shown directly in error messages directly to the user, they're low level technical details and the user almost always wants something more understandable, even if it doesn't provide as much information as a stack trace would!
I say almost always because there are cases (such as in IDEs) where you can consider your users technically competent enough to look at stack traces; indeed in this case they will probably prefer it to a "dumbed down" error message.
However, personally I think stack traces should always be logged somewhere that the user can access so that if they complain that "the program isn't working" you can see exactly what went on if they send you that file.

In some projects, I make a special kind of exception (e.g. UserFriendlyException). This exception type must have a user friendly error message. If I catch such an exception, I can display it to the user.
This makes it possible to use exceptions for user-friendly errors, and prevents that you show very technical messages to the user.

I would argue that you should never show the exception message itself to the user, it should only ever appear in a log. Even if you have purposefully made it user friendly, it should still not be displayed because you cannot internationalize those messages easily. You should come up with some mechanism that your UI layer can understand and resolve that to a code that you can look up an internationalized message to display to your user. I have found that an exception with a "code" attribute/enum works pretty well. Very specific exceptions work too, but that can be messy to maintain.

Related

Unexceptional exceptions

Is this a thing?
I want to throw my own exceptions just to make it easier to handle.
They're unexceptional though because it is likely to happen, not an exceptional case. Such as if the user selects a wrong file type from a browser. Yes I could handle it but it would be far easier if I threw an exception especially for sub methods, since I would need to somehow tell the parent method that the sub method failed so do something differently. This I think is easier with throwing exceptions.
So is it okay to throw an exception in normal situations?
I would have to say answers to this question are to some extent opinion-based, but the general consensus seems to be that it's a bad idea to abuse exceptions for regular flow control.
It's a well-documented anti-pattern, and the primary reasons for it to be considered as such are that:
it obscures your real exceptions,
leads to GOTO-like spaghetti code, and
violates the principle of least astonishment.
The typical use case is:
Present some data to the user
Accept a selection (or a cancellation)
Check the selection (e.g., correct file type)
If correct, return the selection
If not correct, provide an error message (still in the context of this dialog) with the choices "retry" and "abort"
On abort, return a "null value"
On retry, go back to 2.
There is really no need for an exception to handle incorrect entries or even the cancellation (after 2 or 6). Some other exception might be thrown if your program runs into an IOException while accessing the file system or similar.
The only burden the caller should have is to check for a "null value" (null or whatever is suitable) being returned to indicate user's choice of not wanting to do something - an option that should typically be provided.

What is an efficient method to map errors(exceptions) occuring in a J2EE website with suitable error messages?

I am developing a J2EE website for a mini project, and I’m puzzled about exception handling. I have defined several custom exception classes, and they’re thrown from several parts of the website, and they are captured in a custom exception handler. But, i am yet to find a good way to map the occurred Exception to an error message.
To put it simply, if an exception occurs somewhere, I have a global exception handler which captures the thrown exception ( i won't swallow it within a local catch block ), but i need an efficient mechanism by which i should be able to convert it into a suitable error message to be displayed to the end users.
Also, the custom exceptions have a tree hierarchy , which means the top of the tree will have general exceptions and the leaves of the tree would have exceptions defined for a very specific purpose.
The tree would be like
CustomException
Type1Exception
Type11Exception
Type12Exception
Type121Exception
Type122Exception
Type13Exception
Type2Exception
Type21Exception
Type211Exception
Type22Exception
Type3Exception
Type31Exception
Type32Exception
Type33Exception
Type4Exception
Type41Exception
Type411Exception
Type4111Exception
Type4112Exception
Type421Exception
Type4211Exception
Type42Exception
Each exception branch would represent exceptions occurring in specific part of the website. The tree will grow more in future, if more features are added to the website What is the best practice to map the bunch of exceptions to error messages ?
And, is using instanceOf operator and isInstance() method , to check the type of exception, a good practice (in aspects of performance ,scalability and code standards) ?
Each exception branch would represent exceptions occurring in specific
part of the website.
But what if the exception happens in a common component shared by different parts of the website?
Exceptions already tell you where they happened (that's what the stacktrace is for), you don't need to put it in the name. The name is for the reason of the exception (such as IllegalArgumentException or EOFException.
Your design is poor in many ways. You should handle exceptions where you can, either locally with a specific error message (if let's say a user wants to pick a username that's already taken) or globally with a general error message.
Edit:
There are thousands of potential error situations in an application. You can divide them into categories based on what you can do to them. Let's say you try to insert a duplicate username into the database, and an exception is thrown. You catch this and tell the user to choose a different username.
That's the least exceptional case, you might even bypass this by checking if the username exists, instead of relying on an exception.
Then you have a bit more exceptional, let's say you can't connect to the database at all. You don't know why, but you're still prepared, you tell the user that something is wrong with the database, and please try again.
Then you have the most exceptional. You're not prepared for it, you don't have a catch clause for it, it flies up to the global exception handler. All you can do is show the user a generic error message that "Something went wrong", log the error, and notify the maintenance team.
Now the way to design exceptions is based on how much information you know about what happened. You might have a DatabaseException class for all DB related errors, and a DuplicateUserException that extends it to provide more detail. Also note that a DuplicateUserException would never propagate up to a global exception handler. You'd handle it right there, showing the user the screen with the error message. The error message which you'd get from a resource bundle not with the name of the exception, but a general key, such as "exception.user.duplicate".
I think your basic mistake is thinking that you can create a single place responsible for exception handling, just based on the exception type. I suggest that you let that idea go. The global handler should only handle (mainly log) the exception when nobody else will.

How to create an application specific effective exception Hierarchy

I am a newbie with designing stuff though I have some experience as a developer. My question is related to the statement -
"It is always a good practice to design the exception hierarchy at the start of the project"
After much of reading and researching the definition of a checked and unchecked exception is well clear.
However, I still wonder what is the best practices in designing the exception hierarchy for an application. Is the below approach right?
Create your own application specific top level exceptions
MyAppRuntimeException
MyAppCheckedException
Subclass MyAppCheckedException with all your business exceptions where you want the caller to take a specific exception. For example
TryWithADifferentInputException - This is not the right input, correct it
TryAlternateServiceException - This service is not available, but you can choose another service that will do the job
Similarly subclass your runtime exception which spiral up and are captured only by something like the spring exception resolver and display appropriate message on front end.
Another thing that bugs me is how to come up with most of the exception scenarios at the start of the project. What should be the strategy to do so.
Hello hailMurphy and welcome to SO!
IMO, it is not necessary to design an entire exception hierarchy for every app. Rather, you should only introduce new exceptions if none of the existing stock ones adequately address the error you're encountering.
Your TryWithADifferentInputException for instance could probably easily be replaced with an IllegalArgumentException or possibly IllegalStateException. I find that 99% of the time, I'm well able to do with the existing ones.
As for knowing which exceptions to expect before you actually start writing code: The complex parts of your program, such as class structure, algorithms, protocols, etc. should be thought out and documented before you actually fire up your IDE and get hands-on. UML is a common way to do this. During that process, as you're pen-and-papering your algorithm or protocol, try looking at border cases (what happens when this value becomes zero? What if this argument is null? Will my algorithm still work? Good! Will it break? Exception!) and playing devil's advocate (what if the network connection breaks down halfway through my protocol? Can I recover from this, or does it leave me in an unrecoverable state?) you should be able to see exception scenarios.
If you do find yourself in need for creating custom exceptions, derive them directly from whichever ancestor seems most fit - Error, IllegalStateException, RuntimeException, IOException, etc. Don't create your own complete hierarchy unless there is a scenario where you need to only catch all of your own exceptions and none of the stock ones. Honestly, though, I can't see a scenario where that might be useful.
On a more general note, exceptions should be a "last resort" to deal with errors that can't be otherwise recovered from, and not as a form of control flow. If you're expecting something to happen naturally as part of your application (such as bad user input), you should generally not deal with it through exceptions. If you have an algorithm that breaks unrecoverably in a lot of cases, it can be an indication that you haven't found the right one yet.
Well, I am not going to answer all of your questions, but just the parts that I know based in my experience.
The idea of create the exceptions at the begining just have sense if we have the design of the app really clear. I mean, we have to know the flows of the app and what could happen. If we dont know the design more than 80% probably we will change many things, including exceptions hierachy, many times.
Furthermore, If our app is designed correctly and at the coding stage a new exception appears, should be easy the addition in the exceptions tree.
Well I hope be clear for you.
Bye

java - is there a standard way of collecting exceptions?

I have a Java program that parses several different input files. Even when an error is found in this input files, parsing could still continue and collect several other errors too. So what I want to do is instead of throwing and exception and stopping parsing process, I'd like to register the exception to somewhere, and then continue parsing and collect several other errors in similar way, then in the end I want to check if any errors are reported, and fail or continue depending on this.
Of course I can always do this manually by writing ExceptionRegister or whatever classes but I want to know two things:
1) Is there a problem with this approach? Do you know any alternative designs for what I want to do?
2) Is there a standard way of doing this? (e.g. instead of rolling my own classes I'd like to use built-in functionality if possible)
Thanks
EDIT: I don't know why but someone just removed his answer just before I accepted his answer. Anyway, I think simple data structures should work. Basically, I'll write an exception class that collects several error messages. Then I'll call it's throw method which throws itself if it has at least one error message registered.
EDIT2: Here are more clarifications. My problem has nothing to do with parsing. Parsing was just an example because my program does some parsing. Think this: I'm running an algorithm and in case of an error, I can continue the algorithm to collect more errors so that instead of printing one error and when it's fixed, printing second error, I can print this two errors together.
Exceptions should really be used when you can't handle the input anymore. They are the special case where your code says "I give up, I'm missing some information or I wasn't meant for this". This is a grey area on how to define such cases, but the usual philosophy, as put by Bill Venners in this (old!) article is:
Avoid using exceptions to indicate conditions that can reasonably be
expected as part of the typical functioning of the method.
In your case, it sounds like the content you have to parse might be incorrect, but this is expected by your program and doesn't break enough the contract to stop the parsing. On the other hand, an acceptable exception would be valid to use if an error in the syntax of the input causes the rest of the interpretation to fail, for example.
But people still uses exception because they are quite convenient for stopping execution and going up the stack without going in the tedious details of flowing through returns of results. But on its counterpart, they can have tricky results as you leave some unattended state in some objects.
Your requirements sounds more like a validation pattern is required than one single exception that could cause the processing to stop. One exception to stop all processing: if you throw one, the rest will be ignored. But you suggested that you would collect them instead of throwing those. So I'd say, in that case, why use exceptions at all? It seems you do want to return proper results and not stop the program's execution.
Because if you still go down this path, you could have a collection of exceptions to throw at the end. Which one do you throw? Which one takes precedence, in the Exception collector you created?
Take the example of Eclipse, which has this gigantic platform to handle with a massive collection plug-ins contribution. They use a proper communication channel to log any warning and errors, either in problems pane or through the execution of background task. The latter's execution will usually return an IStatus object or a variant. Based on this IStatus object, the code that receives the status decides to act upon it.
Hence personally, I'd develop a similar object that would collect all necessary user's errors (and not program's errors), that does not break the program's execution and an acceptable part of the contract. This object can contain the severity of the error, its source, a hint on how to fix it (this can be a string, or even a method that contains a pinpointing logic for showing the error or possibly a partial automated fix), etc... Once the execution is done, the parsing's result will get these status objects and act on it. If there are errors, inform the user through the UI and log it as well.
So it's basically the same approach as you initially suggested, minus the exceptions and minus the commodity of jumping through the stack that could lead to nasty side-effects and very difficult to debug errors.
I think I understand now. What you are actually trying to do is to collect the parse errors (which you are representing as exceptions) and continue parsing the current input file.
There is no standard way to do this:
The "exception register" is really nothing more than a list of parse error descriptors ... presumably some parser exception. If you can catch the exception at the appropriate point, it is trivial to add it to the "register".
The difficult part is the functionality you are not talking about:
How to capture the location of the error
How to get the parser to continue parsing when it gets a parser error.
The solutions to these depend on how you have implemented your parser.
If you are using a parser generator, there is a good chance that the PGS documentation explains how to implement this.
If you are implementing the parser by hand, you will need to roll your own code to track error locations and do syntax error recovery.
Basically, I'll write an exception class that collects several error messages. Then I'll call it's throw method which throws itself if it has at least one error message registered.
That sounds like an abuse of exceptions. A better idea is to accumulate the errors in a list, and then create / throw the exception if the list is non-empty. Use a static method in a helper class if you want to avoid duplicating code.
An exception that conditionally throws itself is (IMO) bizarre! And creating lots of exceptions that you are unlikely to throw is likely to be inefficient. (Depending on the JVM, the expensive part of exceptions is often creating the exception and capturing the stack frames. The expense can be significant.)

Is it correct or safe to throw an Exception whose message includes the offending value?

Let's say you are writing a generic doSomething method where you check a string argument for validity:
public void doSomething(String argument) {
if(!checkArgument(argument)) {
// Argument is not valid
throw new IllegalArgumentException("Argument " + argument + " is not valid");
}
...
Is throwing an Exception whose message can contain potentially arbitrary text safe? Or can it expose the program to log forging or some other security issues?
Is there any best practice to handle such cases?
It really depends on what you are going to do with the exception after it is thrown.
In general, I'd say this is probably a bad idea. As a rule of thumb you should never "use" unsanitized arguments. Here are a few attack scenarios this might open you up to.
This is for a webpage and you are displaying this error to the user. In this case the attacker could execute a XSS attack, among other things.
This error will be printed to a log. Here it may seem safe, but the attacker still has some (all be it limited) access to your file system. They could use this mechanism to store code for future use, or possibly damage the log (or other aspects of the file system). This is especially true if argument is written byte for byte to a file.
This error will be stored in a database. Here with enough schema information the attacker may be able to alter, or destroy the entirety of the database.
On it's own this might not be enough for an attacker to steal any information, but combined with other bugs this could be used to gain control of the machine. You could do some basic sanitization though and avoid most of these issues.
As suggested by #assylias perform length checking.
Ensure all characters in argument are alphanumeric (or whatever you expect things in arg to be).
If alphanumeric is to restrictive, pass through any whitelist that doesn't include html/javascript/sql syntax characters (e.g. '<','>',';') Usually these characters do not need to be present for debugging anyways.
Generally safe, but you should decide whether to allow exceptions to be visible to end users if the code is executing on a system under your control (e.g. a web server). Showing internal information in error messages in exceptions is a form of Information Leakage as it can reveal information about how your system is built and an attacker can probe for vulnerabilities by forcing exceptions. This may not apply if it is a desktop application, as this is effectively under user control anyway, but extra caution is needed to anything web or internet based.
However, you could add logic to your custom error handler page to only show the details of exceptions that derive from MyUserExceptionClass which you make it your policy to only use when the end user can rectify the error. In this case you'll probably only want to show the message itself and not output any stack trace or other details, in which case your exception message should contain details of the argument name if it is relevant to the end user.
To address the points in diedthreetimes's answer, these should not be of concern to the exception throwing class or the exception class itself. The class that uses the unsanitised data should sanitise it for the context it is output.
e.g.
If output in an HTML page, HTML encode the exception message at point of output, not at point of exception throwing.
The error logging class should sanitise the unsanitised text into the correct format for the log. If there is a character limit or if it is a CSV formatted file then this class should ensure that any commas and quote characters in the message are formatted properly at this point.
If written to the database, it is up to the Data Access Layer to correctly write the information into the database using parameterised queries.
I broadly agree with SilverlightFox's answer. Worry about injection vulnerabilities at the point they occur (and make sure they cannot occur).
However, confidentiality issues are a real problem with exceptions. Elsewhere (unless we have globals) we are dealing with interactions over a single layer-interface. Bring in exceptions and we have non-local issues.
For example:
SSNs are the canonical example of data that needs tight controls. Some low-level parsing library may throw an exception with details of the string. That may be caught and shoved into a log. Neither generic parsing code nor logging code know about SSNs but they've ended up introducing an SSN vulnerability.
Web sites that put exception messages into web pages (sometimes in comments - that doesn't help!) disclose information about the web site implementation that may be helpful to an adversary. Web sites should not do this, but they do. Therefore, you need to think carefully about any code that throws exception and could end up in a web app some day.
Exceptions propagated between processes, or machines, or operating system to pross, or whatever, may carry confidential information.
Where there is mobile code, confidential information may be slip down to less privileged code. File paths are the obvious candidate here.
It's also worth noting that adding mutable data to exceptions is a bad idea, as it needs a deep copy to be safe. It's a shame that 1.4 made Throwable itself "usefully" mutable.
You can log the argument and include a substring in exception.
For your concern on security it depends on access control model of your application and infrastructure.
If server is not accessible to all, then logging is a good idea at least you can have a look at what argument caused exception.
If security is a higher concern, I would suggest storing exception details in a database table along with parameter for analysis.
If you want to go crazy you can encrypt your database column.
In any case I think one would like to have a look at what argument caused exception.
Cheers !!

Categories