Sign up ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free.

I'm currently doing a code review and one of the things I'm noticing are the number of exceptions where the exception message just seems to reiterate where the exception occurred. e.g.

throw new Exception("BulletListControl: CreateChildControls failed.");

All three items in this message I can work out from the rest of the exception. I know the class and method from the stack trace and I know it failed (because I've got an exception).

It got me thinking about what message I put in exception messages. First I create an exception class, if one does not already exist, for the general reason (e.g. PropertyNotFoundException - the why), and then when I throw it the message indicates what went wrong (e.g. "Unable to find property 'IDontExist' on Node 1234" - the what). The where is in the StackTrace. The when may end up in the log (if applicable). The how is for the developer to work out (and fix)

Do you have any other tips for throwing exceptions? Specifically with regard to the creating new types and the exception message.

share|improve this question
Are these for log files or to present to the user? –  Jon Hopkins Dec 23 '10 at 12:14
For debugging only. They may end up in a log. They would not be presented to the user. I'm not a fan of presenting exception messages to the user. –  Colin Mackay Dec 23 '10 at 13:12

5 Answers 5

I'll direct my answer more to what comes after an exception: what's it good for and how should software behave, what should your users do with the exception? A great technique I came across early in my career was to always report problems and errors in 3 parts: context, problem & solution. Using this dicipline changes error handling enormously and makes the software vastly better for the operators to use.

Here's a few examples.

Context: Saving connection pooling configuration changes to disk.
Problem: Write permission denied on file '/xxx/yyy'.
Solution: Grant write permission to the file.

In this case, the operator knows exactly what to do and to which file must be affected. They also know that the connection pooling changes didn't take and should be repeated.

Context: Sending email to '' regarding 'Blah'.
Problem: SMTP connection refused by server ''.
Solution: Contact the mail server administrator to report a service problem.  The email will be sent later. You may want to tell '' about this problem.

I write server side systems and my operators are generally tech savvy first line support. I would write the messages differently for desktop software that have a different audience but include the same information.

Several wonderful things happen if one uses this technique. The software developer is often best placed to know how to solve the problems in their own code so encoding solutions in this way as you write the code is of massive benefit to end users who are at a disadvantage finding solutions since they are often missing information about what exactly the software was doing. Anyone who has ever read an Oracle error message will know what I mean.

The second wonderful thing that comes to mind is when you find yourself trying to describe a solution in your exception and you're writing "Check X and if A then B else C". This is a very clear and obvious sign that your exception is being checked in the wrong place. You the programmer have the capacity to compare things in code so "if" statements should be run in code, why involve the user in something that can be automated? Chances are it's from deeper in the code and someone has done the lazy thing and thrown IOException from any number of methods and caught potential errors from all of them in a block of calling code that cannot adequately describe what went wrong, what the specific context is and how to fix it. This encourages you to write finer grain errors, catch and handle them in the right place in your code so that you can articulate properly the steps the operator should take.

At one company we had top notch operators who got to know the software really well and kept their own "run book" that augmented our error reporting and suggested solutions. To recognise this the software started including wiki links to the run book in exceptions so that a basic explanation was available as well as links to more advanced discussion and observations by the operators over time.

If you've had the dicipline to try this technique, it becomes much more obvious what you should name your exceptions in code when creating your own. NonRecoverableConfigurationReadFailedException becomes a bit of shorthand for what you're about to describe more fully to the operator. I like being verbose and I think that will be easier for the next developer who touches my code to interpret.

share|improve this answer
+1 This is a good system. Which is more important: Being sure the information gets across, or using short words? –  Michael K Dec 23 '10 at 15:04
+1 for i like the solution of including , context,problem,solution –  WebDev Dec 23 '10 at 17:03
This technique is so helpful. I'm definitely going to utilize it. –  Kid Diamond Mar 30 at 9:11

In this more recent question I made the point that exceptions should not contain a message at all. In my opinion, the fact that they do is a huge misconception. What I am proposing is that

The "message" of the exception is the (fully qualified) class name of the exception.

An exception should contain within its own member variables as many details as possible about precisely what happened; for example, an IndexOutOfRangeException should contain the index value that was found to be invalid, as well as the upper and lower values that were valid at the moment that the exception was thrown. This way, using reflection you can have a message automatically constructed which reads like this: IndexOutOfRangeException: index = -1; min=0; max=5 and this, together with the stack trace, should be all the objective information that you need in order to troubleshoot the problem. Formatting it into a pretty message like "index -1 was not between 0 and 5" does not add any value.

In your particular example, the NodePropertyNotFoundException class would contain the name of the property that was not found, and a reference to the node that did not contain the property. This is important: it should not contain the name of the node; it should contain a reference to the actual node. In your particular case this may not be necessary, but it is a matter of principle and a preferred way of thinking: the primary concern when constructing an exception is that it must be usable by code which might catch it. Usability by humans is an important, but only secondary concern.

This takes care of the very frustrating situation which you may have witnessed at some point in time in your career, where you may have caught an exception containing vital information about what happened within the message text, but not in within its member variables, so you had to do string parsing of the text in order to figure out what happened, hoping that the message text will stay the same in future versions of the underlying layer, and praying that the message text will not be in some foreign language when your program is run in other countries.

Of course, since the class name of the exception is the message of the exception, (and the member variables of the exception are the specific details,) this means that you need lots and lots of different exceptions to convey all the different messages, and that is fine.

Now, sometimes, as we write code, we come across an erroneous situation for which we just want to quickly code a throw statement and proceed writing our code instead of having to interrupt what we are doing to go create a new exception class so that we can throw it right there. For these cases, I have a GenericException class which does in fact accept a string message as a construction-time parameter, but the constructor of this exception class is adorned with a great big huge bright purple FIXME XXX TODO comment stating that every single instantiation of this class must be replaced with an instantiation of some more specialized exception class before the software system gets released, preferably before the code gets committed.

share|improve this answer
If you're in a language that doesn't have a GC, like C++, you should be very careful about putting references to arbitrary data into exceptions that you send up the stack. Chances are, whatever you're referencing has been destroyed by the time the exception is caught. –  Sebastian Redl Apr 14 at 15:13
@SebastianRedl True. And the same could apply to C# and Java if the node object is guarded by a using-disposable (in C#) or try-with-resources (in Java) clause: the object stored with the exception would be disposed/closed, making it illegal to access it in order to get any useful information out of it at the place where the exception is handled. I suppose that in these cases some sort of summary of the object should be stored within the exception, instead of the object itself. I cannot think of a fool-proof way to generically handle this for all cases. –  Mike Nakis Apr 14 at 18:42

As a general rule, an exception should help developers pinpoint the cause by giving useful information (expected values, actual value, possible causes/solution, etc.).

New exception types should be created when none of the built-in types make sense. A specific type enables other developers to catch a specific exception and handle it. If the developer would know how to handle your exception but the type is Exception, he won't be able to handle it properly.

share|improve this answer
+1 - expected values vs actual values are extremely useful. In the example given in the question, you should not simply say that a method failed, but why it failed (basically, the exact command that failed, and the circumstances that caused the fail.) –  Felix Dombek Dec 23 '10 at 13:45

The things you want to be looking for to "add" to the exception are those elements of data that are not inherent in the exception or the stack trace. Whether those are part of the "message" or need to be attached when logged is an interesting question.

As you've already noted, the exception proably tells you what, the stacktrace probably tells you where but the "why" may be more involved (should be, one would hope) than just going to peer at a line or two and saying "doh! Of course". This is even more true when logging errors in production code - I've all too often been bitten by bad data thats found its way into a live system that doesn't exist in our test systems. Somethig as simple as knowing what the ID is of the record in the database that's causing (or contributing) to the error can save significant amounts of time.

So... Either listed or, for .NET, added to the logged exceptions data collection (c.f. @Plip!):

  • Parameters (this can get a bit interesting - you can't add to the data collection if it won't serialize and sometimes a single parameter can be surprisingly complex)
  • The additional data returned by ADO.NET or Linq to SQL or similar (this can also get a bit interesting!).
  • Whatever else might not be apparent.

Some things, of course, you won't know you need until you don't have them in your initial error report/log. Some things you don't realise you can get until you find you need them.

share|improve this answer

Don't create new types if you can help it. They can cause extra confusion, complexity and lead to more code to maintain. They may make your code had to extend. Designing an exception hierarchy requires a lot of though and testing. It's not an after thought. It's often best to use the built in language exception hierarchy.

The content of the exception message dependents on the receiver of the message - so you have to put yourself in that person's shoes.

A support engineer will need to be able to identify the source of the error as quickly as possible. Include a short descriptive string plus any data that can help troubleshoot the issue. Always include the stack trace - if you can - this will be the only true source of information.

Presenting errors to general users of your system depends on the type of the error: if the user can fix the problem, by providing different input for example, then a concise descriptive message is required. If the user can't fix the problem, then it's best to state an error has occurred and log/send an error to support (using guidelines above).

Also - don't throw up a big "HALT ERROR!" icon. It's an error - it's not the end of the world.

So in summary: think about the actors and use cases for your system. Place yourself in those user's shoes. Be helpful. Be nice. Think about this up front in your system design. From the perspective of your users - these exception cases and how the system handles them, are just as important as the normal cases in your system.

share|improve this answer
I disagree. There are many good reasons to implement your own exceptions when the language API doesn't cover your exact needs. One reason is that in a method where multiple things may fail, you can write different catch clauses for different types of exceptions, where you can react to the exact problem. Another is that you can separate multiple layers of exceptions representing different layers of abstraction, where the exact layer that an exception belongs to can be encoded in its type. Just using "Exception" or "IllegalStateException" and a message string doesn't help much there. –  Felix Dombek Dec 23 '10 at 13:51

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.