[.net] Debugging Help - Exceptions

Started by
11 comments, last by TheTroll 16 years ago
Hi, I'm not very experienced with .NET - and I'm having some trouble dealing with a particular exception I keep getting. I've got a whole bunch of game unit definitions in an XML file. When I parse the XML file, I place each unit in a big Dictionary, with the unit name as the key. It's a requirement that every unit has a unique name, so this should be fine. But if I make a mistake and accidentally make a unit with an identical name in the XML file, the program throws an exception when I call Add(). This is fine, and that's what I want it to do. But the exception seems to be seriously lacking in information. It just says, "An item with the same key has already been added." I was hoping that .NET would be able to do a little better than that, at the very least I need the key so I can determine where the error is and how to fix it. Normally, I'd just use the debugger to break when the exception is thrown, and use the debugger to find the key. But I want to be able to intercept the exception, find the offending key, and display a message to the user. Anyone have any ideas?
NextWar: The Quest for Earth available now for Windows Phone 7.
Advertisement
First of all exceptions are to be used for things that are not expected in normal operation of the program. From your description it sounds like this is pretty much expected. So you should instead test before the add to see if it already exists.

theTroll
Quote:Original post by TheTroll
First of all exceptions are to be used for things that are not expected in normal operation of the program.


I'd say surrounding with a try catch block would probably be fine. You could do the following:

try{    //Dictionary add in here}catch (ArgumentException){    //If an argument exception was thrown, the same key was added twice, handle it}
Quote:Original post by Hutch
Quote:Original post by TheTroll
First of all exceptions are to be used for things that are not expected in normal operation of the program.


I'd say surrounding with a try catch block would probably be fine. You could do the following:

*** Source Snippet Removed ***


No. TheTroll is right, there's no reason to use exceptions here.

The Dictionary class has methods for checking if a key already exists. First check if the key exists with Dictionary.ContainsKey. If it doesn't, add the item. If it does, do nothing, or whatever is appropriate for your application.
Now if you do want an exception here and want more information this is what you can do.

Well you can do it two ways;

First you can in the function that does the Add to the dictionary test to see if the Key already exists using the method built in to the dictionary, it is does throw a standard exception using a string as a parameter with all of the information you need.

The other way is to create your own exception with custom exception arguments that have all the information you need. I prefer the second method because it forces you to add all the information you would need for debugging the problem.

Remember letting the system throw an exception is never as effective as you throwing a custom one.

Because I don't know your application I can't say for sure if this really should be an exception or not, but you should ask yourself the following questions;
1. Will this cause my application to crash, give bad information or not work as intended.
2. Does this only happen on rare occasions, not expected in normal operations.
3. Is high performance not needed in this section of code.

If you answer no to any of these questions you really shouldn't be using throw-catch situations.

theTroll
Quote:Original post by TheTroll
If you answer no to any of these questions you really shouldn't be using throw-catch situations.


Just out of curiosity, suppose that performance was not an issue at all, would there be a reason not to use exeptions everywhere? I'm using them extensively in my code (which is in C++, but that doesn't really matter), and I think they make my code a lot cleaner than if I had to check for error codes.
The main thing to remember is that exceptions are not to be used for program control. They are to prevent the program from critical errors (crashes, bad information, ect.) only. Also they are not suppose to be used to prevent things that should be expected in normal operation of the program. In network communications it would be expected that there would be a drop of connection or a drop of packets, so those should no be exceptions but handled by normal code.

theTroll
This is more the case of, "for some reason the user edited the XML files containing object definitions for the program. If something wrong was detected in the XML, I want to handle that exception and report the problem, exactly, to the user. Then error out."

So it's certainly not an expected situation, and should never occur during program execution. It'll only occur if, through my own idiocy or because someone was tampering with the file, an error was found. The XML is parsed during load time, so this code path is only ever executed once, and it's executed when performance doesn't matter.

And I've decided to take your advice and create a custom exception class, and use try/catch blocks and functions like ContainsKey() to find these errors myself and throw a custom exception.

Thanks, all.
NextWar: The Quest for Earth available now for Windows Phone 7.
Yup sounds like a perfect use of an exceptions.

theTroll
It's generally considered bad practice to subclass exceptions unless you have a valid reason for handling them differently in a mixed context (meaning, you can't replace catch(X e) with catch(Y e) where X is your exception and Y is its base or another existing exception).

In this case, it doesn't seem like you need a new subclass. You can probably just throw new InvalidOperationException("your message here"), or an existing framework or XML exception, instead of creating your own exception subclass. In your situation, you want to report an error to the user when loading fails, essentially. The code path you'd take when it fails because they edit the XML manually and when it fails for some other reason are similar -- pop up a dialog, display the exception's Message property, and do what you need to do. There's no reason to have a catch for YouDickedUpTheXmlException and a catch for any other failures that can occur during the load process (such as the key duplication which may crop up elsewhere, or maybe a 'key not found' exception; all of which are standard framework stuff). InvalidOperationException is the general fallback, although there may be another that is more suitable to your specific problem out there.

I'm fairly sure subclassing your own at this juncture is unnecessary and introduces a lot of annoyance and boilerplate junk (serializing exceptions, providing the appropriate semantics, et cetera) -- that is, provided you want to do it correctly.

N.B: System.Exception contains a general dictionary of key-value pairs (Data) for associating custom properties and bits of data with an exception. It is rare that you need to subclass just to tack some extra data along in the payload in a code-accessible fashion.

This topic is closed to new replies.

Advertisement