Exceptions in ADO.Net 2.0 [Siraj Lala]


I’d like to briefly talk about some of the work we have done in ADO.NET 2.0, for improvement of Errors and Exception usage. In ADO.NET 1.1, several error messages were generic and didn’t have enough detail to make them actionable. An example of this is the infamous “General network error” that could occur in variety of cases. In ADO.NET 2.0, we now surface the exceptions that we get when making calls to the lower network layer (SNIX – the network transport layer used by SqlClient). These exceptions are encapsulated  in the exception thrown by SqlClient, with additional information at the API level.
 
From the implementation perspective, the errors coming from SNIX are wrapped in a Sqlclient level message that describes the task SqlClient was trying to perform when this error occurred. The result being that the SNIX message is included in the SqlClient-level message. The general syntax we used is:
 <sqlclient message> (provider:<SNIX provider>, error: <SNIX error code> - <SNIX error message>)
 
This did make the error messages more verbose, but it also made them much more meaningful and actionable. Let me illustrate this with an example. Let’s say you force encryption from the client-side (encrypt=true) but the client was not able to validate the servers certificate.
In ADO.NET 1.1 this would have resulted in an exception message – “SSL Security Error.” 
The same scenario in ADO.NET 2.0 gives the error message - “A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: SSL Provider, error: 0 - A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.)”.
 
Here’s another example. Let’s say the application loses network connectivity while its reading results from a SqlDataReader.
In ADO.NET 1.1 this would have resulted in an exception message – “General network error.  Check your network documentation.”
This same scenario in ADO.NET 2.0 gives the error message – “A transport-level error has occurred when receiving results from the server. (provider: TCP Provider, error: 0 - The specified network name is no longer available.)”.
 
I also wanted to make a brief mention of a new Exception base class we added in .NET 2.0 – System.Data.Common.DbException. This was added  to enable  catching provider exceptions in a generic way, when writing provider agnostic code . We made the provider specific exceptions (i.e SqlException, OracleException, OleDbException, OdbcException) derive from DbException. Hence, if you are writing provider-agnostic code, you can catch DbException if all you are interested in catching are the provider specific exceptions.



Siraj Lala
Test Lead - ADO.Net team


Disclaimer: This posting is provided "AS IS" with no warranties, and confers no rights

Comments (10)
  1. Sahil Malik says:

    Fantastic, I have given this decent coverage in my book (chapter #2) regards the new exception structure and enhancements in ADO.NET 2.0.

    The new inheritance model is incredibly useful.

    I have a question – would you say that it is maybe too bold to make the following statement?

    "DbException deals with all exceptions that generate out of disconnected data cache or provider independent code?"

  2. MSDN Archive says:

    Hi Sahil, Its nice to know that this would be covered in your book.

    With regards to your question, DbException will not help for exceptions coming out of disconnected data cache (like DBConcurrencyException). These will have to handled separately. Only the provider specific derive from DbException(base). Hope that helps.

    -Sushil Chordia[MS]

  3. Sahil Malik says:

    Thanks for your answer Sushil,

    Actually I screwed up, I asked the wrong question. (I’m getting more and more absent minded by the minute)

    Here is the right question –

    Would you say that it is maybe too bold to make the following statement?

    "System.Data.DataException deals with all exceptions that generate out of disconnected data cache or provider independent code?"

    (Not DbException, DataException :-))

    Thanks !! 🙂

  4. Siraj Lala says:

    Hi Sahil. No, we cannot make that statement. When working with a disconnected Data cache you may get various exceptions that will not be caught if only catching DataException. An example is exceptions got when calling RealXmlSchema.

    Thx.

    siraj.

  5. Sahil Malik says:

    Ok can we say "System.Data.DataException deals with exceptions coming out of Disconnected data?"

    I am trying to categorize the exceptions for easy understanding .. thats all 🙂

  6. Siraj Lala says:

    I got the answer from Ravinder (our DataSet tester). The exceptions which are thrown from DataSet API are mainly exceptions of type DataException or exceptions that are derived from DataException. This is true for most scenarios. However, there are quite a few exceptions to this rule that need to be considered.

    a) DataSet has API to read and write XSD/XML. The exceptions from XSD/XML parsing are directly propagated back to the user in this case.

    b) Calling DataSet API with invalid arguments may also cause ArgumentException, InvalidOperationException, etc. which are not derived from DataException.

    c) Also remoting/transporting dataset over the wire will propagate the exceptions coming from the remoting framework directly to the user.

    Hope this clarifies it.

  7. TC says:

    All hail the death of the GNE!

  8. Sahil Malik says:

    Fantastic. Thank you Siraj, this sounds perfect. 🙂

Comments are closed.

Skip to main content