coarse exception granularity |
|
Author |
Message |
sean_kirkpatrick
|
Posted: .NET Base Class Library, coarse exception granularity |
Top |
I'm struggling with what I perceive to be a very coarse level of exception definition in the framework. Even though my example is related to a database, I think it's probably more appropriately asked here, since I think the issue is wider than ADO. If not, I'll repost in the appropriate forum.
Doing the following, the same exception is thrown, though the error is actually two very distinct things.
dim sSql as string = "" dim DS as DataSet dim adaptor as OleDbAdaptor = new OleDbAdaptor(sSql, dbConnection) adaptor.Fill(DS)
throws System.Data.OleDb.OleDbException, with a message that says "Command text was not set for the command object."
However,
sSql = "select * from foo"
where table foo does not exist causes the same exception to be thrown but the message is very different:
cannot find the input table or query 'foo'
In the olden days, it used to be that I could look at Err.Number - actually I can still do that, but in almost all cases, Err.Number returns 5 - and set up a select case to take action on the error that was returned. I had always imagined that the Exception handling mechanism would give me fairly fine-grained control over what the error was by using typed exceptions and Catch blocks appropriately defined. However, it seems that the best that I can get, in this particular case, is
"Uh oh, A Problem Happened Here"
and I'm left with parsing the Message to find out just what went wrong. How can this be an improvement
I note that in the case of the IO namespace, there are some greater number of exceptions that can be thrown, FileNotFoundException, EndOfStreamException, etc., but in the pantheon of what COULD happen in a running program, it doesn't seem like the pre-defined exceptions are nearly rich enough.
I must be missing something very fundamental to the Exception mechanism. Can someone explain my misconception or point me someplace that does
Thanks!
Sean
.NET Development11
|
|
|
|
|
CommonGenius.com
|
Posted: .NET Base Class Library, coarse exception granularity |
Top |
OleDbException relies on the chosen oledb driver to provide error information. It cannot get any more specific, because the OleDb standard only requires that providers return an error number and a description (and they don't even have to supply that much). Also, the majority of errors returned through oledb are provider specific. However, you can check the OleDbException.ErrorCode property for the error; again, however, this is provided by the oledb driver, and so is out of the control of the .NET framework.
As far as other exceptions go, I have found the .NET exception hierarchy to be remarkably rich in general, especially when compared to other languages/frameworks. Is there something specific you are looking for and not finding
|
|
|
|
|
sean_kirkpatrick
|
Posted: .NET Base Class Library, coarse exception granularity |
Top |
Thanks for your reply.
I guess that my expectation was that there would be an enormous number of exceptions that I could catch - someone posted a tool on the web that walked the BCL and reported the # of exceptions, on the order of 150 or so. That surprised me as with the wealth of classes and such in the framework, I somehow assumed that there would be thousands of exceptions instead of less than two hundred. And in my experimentation with OleDb, getting the same exception for two very different errors surprised me as well.
What I didn't get, and your reply gave me, was an understanding that I had missed vis a vis, an exception is a class that has properties, one of which (in the OleDb case), was the error number that can, I presume, give me more detailed information about the source of the error.
In the past, my exception handlers were generic, that is,
Try
Catch ex as Exception
End Try
I now see that this isn't good enough. Now I need to do something like
Try
Catch ex as OleDbException
Select case ex.ErrorCode
case -1
blah
case -2
blah
End Try
Conceptually, the exception gets my attention and forces me to acknowledge the problem, and I can further diagnose it if I need to.
So, I think you've helped me understand what I was missing. Thanks.
Sean
|
|
|
|
|
CommonGenius.com
|
Posted: .NET Base Class Library, coarse exception granularity |
Top |
Glad I could help. You are right, in general you should never catch the Exception class; you should only catch exceptions that can be responded to at that point in the code. If you need to do something when an exception is thrown, but you're not actually "handling" the exception, you can use catch by itself, and throw by itself at the end of the handler. This is a common pattern when rolling back database transactions.
As to the number of exceptions, its important to remember that the goal of the exception hiearchy is not to provide an exception for every single possible thing that could go wrong in a managed application; as you have pointed out, there would be thousands, maybe even hundreds of thousands of exception classes. The goal was to create enough depth and breadth so that you could appropriately target your exception handlers. The InvalidOperationException is a good example. There are a couple of derived exceptions for special cases, but for the most part, implementations will simply throw the InvalidOperationException. The MoveNext method of an enumerator will throw an InvalidOperationException if the collection has been modified since the enumerator was created. Why isn't there a CollectionModifiedException Because it isn't necessary; the InvalidOperationException is sufficient to signal that the problem has occurred. And the great thing is, if you find yourself in a situation that requires more detailed exceptions than the framework provides, you can always create your own.
My biggest problem with exception handling in C# is that you can't use the same handler for multiple exception types without handling their common base class, which may not be appropriate. Hopefully MS will come up with a solution for that at some point.
|
|
|
|
|
|
|