views:

55

answers:

4

I have repeatedly found myself in situations where I want to catch an exception (in .net), but there may be multiple exceptions with different messages that I want to handle differently.

When I view the exception in a debugger, I usually cannot find any piece of metadata that shows me a unique number representing that particular exception, so I end up writing string comparisons. The exception class is the same.

This is tedious and just seems wrong. Am I missing some good way to uniquely identify exceptions without doing a string comparison? Or do I just happen to work with some bad libraries that don't throw exceptions with good metadata? (Examples so far included ADODB, and OpenNETCF).

pseudocode explaining what i'm describing:

Try
...
Catch myexception as System.Runtime.InteropServices.COMException
   switch(myexception.message){
      case "oneexceptionmessage":
         handleOneException()
      case "twoexceptionmessage":
         handleTwoException()
   }
End Try

End Try

  • Exception types are different
  • Inner exceptions are null
  • HResults may be different, but aren't normally accessible as protected properties
A: 

Instead of using the message of the exception class, the OOP way of doing things would suggest that you create a subclass to represent each of your exceptional circumstances. This way would be, most importantly, strongly typed and there would be no string comparison.

Scott M.
@Scott - these are exceptions from third parties, other libraries I am using. I will update to make that more clear.
pc1oad1etter
then if the string is the only differing property, you're stuck =/. djacobson has the right idea though: find a way to encapsulate your comparison code and maintain it in one place.
Scott M.
A: 

Put multiple catch statements in order from most specific to least specific

Try

Catch dboe as DivideByZeroException

Catch oome as OutOfMemoryException

Catch ...

Catch e as Exception

End Try
Jeremy
They are aware of this. The problem is they are all one `Exception` type with different values in the message property.
ChaosPandion
+1  A: 

You may wish to follow Scott's suggestion and create your own set of Exception classes (based on your observation of what the libraries throw) anyway, especially if we're talking about a large app (or set of them) that all use those libraries.

I'm suggesting a sort of exception-factory class, that encapsulates all the "tedious / wrong" string comparison and generates appropriate exceptions of your own for the calling code to handle or re-throw. This would require the exception handlers in your calling code to pass exceptions they catch to the factory in order to obtain a more-useful result. Might be overkill, but at least you only write the string comparisons once, in one place...

djacobson
A: 

Though I haven't seen it in the debugger, I looked up the documentation for the handheld library we use and saw HResult property. I now see that I can reference this for the database comexceptions too.

I had not noticed it before because I was simply browsing through values in the debugger, and it wasn't there.

Maybe these are always unique?

This is how the documentation describes this property being used - thought I'm not clear if it's enforced that any Subclass of Exception would always enforce this.

pc1oad1etter
.... except HResult is a protected property. Surely you don't have to subclass and cast this somehow to figure this out?
pc1oad1etter
Typically if an Exception class contains an HRESULT, that HRESULT value was used to generate the Message string. It's unlikely that two items with the same HRESULT value will have a different Message. However, you're interested in checking the type of error based on something better than the string. In that case you can strongly consider peeking at the HResult property. This does in fact require cheating with reflection. Subclassing won't help you here as you cannot cast from base to derived if the base wasn't originally created as derived.
Tergiver
@Tergiver: not necessarily. Their `Exception` class may derive from an `Exception` class that contains the `HResult` property.
John Saunders
@pc1load1etter: Please edit your question to add this sort of information, instead of adding an answer (since this does not answer your question).
John Saunders
@John: That's why I chose the word 'typically'..
Tergiver
@pc1oad1letter: It's better than comparing strings. Especially if this is third party code. It's possible (again, not a word that conveys certainty) that the exception strings are localized.
Tergiver
@Tergiver: if that's your reason for using "typically", then you should rephrase. Simply inheriting from a class that has an `HResult` property doesn't indicate intent to set `HResult` to the value that caused the error. You might want to say, "Sometimes if an Exception class contains an HRESULT".
John Saunders
@John: But that would be arguing frequency and since I have no data to support such an argument (either way), I will just leave with both our comments for all to read.
Tergiver
@John - I have added some more information to the question, but at the time I genuinely thought I had found the answer. Thus, I provided it as an answer.
pc1oad1etter