Sign in to follow this  
Sc4Freak

[.net] Debugging Help - Exceptions

Recommended Posts

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?

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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
}

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
jpetrie this might actually be the first time I have ever disagreed with you.

Exceptions should be specific to the "critical situation" you are trying to catch. In this case you are not trying to catch a InvalidOperationException, you are trying to catch an Parsing problem in the XML file. So I feel in this case a custom Exception is exactly what is called for. Something like XMLParseException("message here"), would let the person know that they hosed the XML file when they were messing around with it.

I agree in general there is no reason to create new exceptions when one of the current ones would work. But one of the things I hate is when you get an exception and you really have no idea what it means because all they do is use the basic Exception.

When it is a specific situation that is not covered by basic exceptions, create on that will let the developer and users know why the exception was thrown.

theTroll

Share this post


Link to post
Share on other sites
Quote:
Original post by TheTroll
Something like XMLParseException("message here"), would let the person know that they hosed the XML file when they were messing around with it.


But wouldn't InvalidOperationException("You hosed the XML file") tell them the same thing?

Share this post


Link to post
Share on other sites
Quote:
Original post by Gage64
Quote:
Original post by TheTroll
Something like XMLParseException("message here"), would let the person know that they hosed the XML file when they were messing around with it.


But wouldn't InvalidOperationException("You hosed the XML file") tell them the same thing?


I guess I acutally wrote the exception call wrong, because it was not the way I was thinking about it. XMLFileParseException(XMLFileParseExceptionArgs args, "message here") I forgot you had to include the arguments for the Exception. In the arguments I would have things like; file name, line number, string that gave the error, dictionary key and value. This would give all of the information you would need to understand the exception and fix it quickly.

In my opinion way to many programmers just go with generic exceptions that do not give enough information to understand the problem. With a little more time and effort they could write exceptions that actually help fix the problem, instead of just letting you know you can't continue. I think this is a lot like the "old" days when people would not catch the return codes from functions to see if there were errors or what happened.

Good code lets the programmer and the user understand what is wrong when it breaks.

theTroll

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this