last day (16 days later) » 

02:38
82
A: Why do many exception messages not contain useful details?

Mike NakisExceptions do not contain useful details because the concept of exceptions has not matured yet enough within the software engineering discipline, so many programmers do not understand them fully, and therefore they do not treat them properly. Yes, IndexOutOfRangeException should contain the prec...

I've looked over some of the exception classes in the .NET Framework, and it turns out there are plenty of opportunities for adding this kind of information programmatically. So I guess the question resolves to "why don't they." But +1 for the whole "human-readable" thing.
Yeah, beats me. But luckily, this means that there is room for things to mature in the future.
I don't agree that exceptions shouldn't contain a human-readable component. At some level, you may want to create a log message regarding the exception. I'd argue that logging a stack trace to a user-readable log file is exposing implementation details that you don't want to expose, so the human readable message should be logged. When presented with the log file that contains the error, developers should have a starting point to begin their debugging and be able to force the exception to happen. The human-readable component should be appropriately detailed without giving away implementation.
so programmer's aren't human? Looking at my colleagues this confirms some suspicions I've had for some time...
Sure, I almost agree that an exception should contain a code only and that an "error message" is redundant in such cases. However, this just shifts the problem to a stack of error codes which requires even more rigour in writing them, at least with an error message you can type out whatever you like at the time and prevents a plethora of exception objects being defined for every error case.
@ThomasOwens I amended my answer to address your concern.
@gbjbaanb well, by human-readable I meant user-readable. But of course yes, any fool knows we programmers are hardly human.
@gbjbaanb I am afraid you misunderstood me: I was definitely not talking about error codes. I shall repeat myself: the message of the exception is the (fully qualified) class name of the exception.
02:38
@MikeNakis fundamentally, what's the difference? A code is a value that means something, whether it is an int or a pointer or a compiled runtime object. They're all a single value, no matter how you dress them up differently. You may be thinking of C-style #defines when I say "error code" but that's not necessarily the case. Single value however is.
Again, there's nothing wrong with letting the user see the entire stack trace, as long as the software is client-side. Every professional software project I've ever worked on, and most of the amateur ones as well, contained a logging system that would generate a full error dump when an unhandled exception was raised, including full stack traces of all currently-running threads in the process. And the user could (gasp, oh horror!) look at it any time he wanted, since that is necessary (not simply useful, but required) in order to send the error message back to us! What is wrong with that?
@gbjbaanb the difference is that in the case of class names, for the most part you already have them, you don't have to invest any rigour in coming up with new ones, and they are hierarchical (with inheritance) and extensible: you can write a new module which extends the exceptions of an existing module without having to modify the source code of the existing module.
@MasonWheeler of course, in many scenarios it is okay. But in this discussion (and in other answers) we are addressing the issue of what to do when it is not okay.
I have a dream now - to program in a world where software is through-and-through designed with this kind of attention to exception handling and logging. If only we could get back all the person-days that have been lost to trying to figure out what an error means and what generated it when it was something stupidly trivial that we'd have easily solved if it was just made clear where the error was coming precisely (with variable values included)...
It just dawned on me that there is absolutely no reason why someone couldn't give ArgumentOutOfBoundsException this functionality and submit the pull request...
This is a great answer and philosophy, but I'm a little skeptical about storing binary serializations in log files. I might favor something more portable and slightly more human readable like JSON, so that some kind of binary reader isn't required to view the details and giving programmers more options for readers. (E.g., maybe the best reader is in .NET but I'm writing Java.)
02:38
I'm also not convinced with respect to binary-only log files. Mainly because of my experience with systemd. Its special tool for viewing these logs is quite confusing and appears to have been designed by a committee of Shakespeare's monkeys. Consider that, for a web application, the first person to see your exception is often going to be the sysadmin, and he is going to want to determine if it's something he needs to fix (e.g. the disk ran out of space) or pass back to the developers.
@MikeNakis but you do not "already have them" - somebody somewhere made them up. They could have made up #define return codes just as easily TBH. Think it through - you're just dressing up one system with something better looking. Now, putting codes or text in the exception objects, that makes more sense and starts to build error information that helps. Eg IndexOutOfBounds passing the index that was used so you can see if it was uninitialised value, -1 or 7 in a 6-element collection.
@jpmc26 the stream does not have to be binary, so I amended my answer to reflect that. The point I am trying to make is that if you don't want users to see it, then you have to encrypt it, meaning that you will need a tool to view it, in which case the pre-encryption stream might as well be binary, which would in turn be sufficient to prevent most users from seeing it, thus making encryption unnecessary.
@MichaelHampton the log files do not have to be binary; they may be binary if you want privacy and / or performance. I amended my answer to reflect that. It is just that with a binary log file serialization of exceptions comes practically for free. Also, I would not judge an entire methodology based on one or two possibly unfortunate implementations.
Servers shouldn't be sending out details from a security perspective all my server error messages just asks the user to try again and gives out a support code so I can look at the exceptions which do contain everything I need to debug. They added Data for a reason I even serialize full pocos sometimes into the data section for debugging. I also do use Application defined exceptions for very specific things like the answer says I never implement a message. I think it's time to issue pull requests on the open sources parts of the framework ;)
I don't agree that an exception message is its own name. For example. We do not want to create an exceptions for every single possible error. Furthermore some exceptions like System.Runtime.Remoting.ServerException are not very informative at all. The message can save lots of hours. And programmer time is money.
@user119591 If your ServerException does not have a Cause which is some more specific exception, explaining precisely what went wrong, then your ServerException is as good as the proverbial "An unknown error occurred" message. Good luck with that.
02:38
@user119591: And in some cases the Cause is better that nothing but not too helpfull. For example: Caused by NullPointerException in org.apache.FooBar. Now you need to A) download Apache sources, B) understand what it is happening in this exception. Compare it with: Unable to start server. Port 80 is already in use.
@gbjbaanb No, Mike is correct. An exception class is fundamentally different than an error code. Exceptions have descriptive, compiler enforced names that communicate the actual error via the name. The name is usually enough to make sense of what the exception means, and a little documentation on the exception class is sufficient when it's not. It's sufficiently easy/reliable to write the correct exception name, as opposed to choosing the correct error code. And the compiler or runtime ensures the existence of the exception you use. Error codes have none of these benefits.
@jpmc26 so apply what you said to a const int. It can have just as good a descriptive name, can be commented equally well, its easy to type out the name (even via intellisense) and the compile will ensure the existence of this code. You're mistaking the type of thing with the information it conveys. Hence an exception class that is simply a language entity is no different from a code - they both convey 1 piece of information that is equally useful in diagnosing the problem. Thus I think adding more info is better, don't get caught up in exception v error ideology, think of the data.
This answers seems highly geared towards maintaining a cooperate software environment. In other environments their are other important things to consider. For example while programming it is pretty important for the IDE/commandline/server/browser to print out human readable and informative errors as you compile and test the code.not just create an encrypted binary logfile.
The log file does not have to be binary. It can, possibly, be binary. The point I am making is that it needs to be thought of as a stream, into which exceptions can be serialized, which in turn serves to support the argument that exceptions do not have to create human-readable messages for storing in log files. So, if you have no security issues, the log file could be plain text xml, containing something like <exception className="IndexOutOfRangeException" index="-1" minValid="0" maxValid="5"><StackFrame/>...</exception>
w3d
w3d
"the concept of exceptions has not matured yet enough within the software engineering discipline" - say what? Really?!
02:38
@w3d: I think the fact that so many exceptions contain English "explanations" is proof that that statement is correct.
I vehemently disagree with the idea that logs should be obfuscated, binary, or otherwise hidden from the user. In the oracle table not found exception mentioned, an admin may be able to understand that a table is missing, check his database backups, and find that yes, that table is missing... let's restore the good backup and be on our way and there is no need to send some binary log file to the developers and hope they get back to you. Another example are Windows NT crash exceptions, aka BSODs. An admin might not be able to fix the bug but he can see which driver is broken and disable it.
@gbjbaanb Think about the data? Sure. First, the compiler/runtime can't enforce that you even use a named constant for your error code, since the type is just a string or int. Anyone can throw a magic number/string into any location where the error occurs, so a descriptive name might not even exist. Second, being a simple string or int type, it can't have additional contextual details attached to it to aid in diagnosing. This a major point of this answer: exceptions have the ability to carry more data and we should be using it. At minimum, an exception is a full DTO, not just a code.

  last day (16 days later) »