Handling Errors
Errors in ADO.NET are handled the same way as elsewhere in the .NET frameworkyou can catch exceptions that are thrown by objects involved in connecting to and interacting with the database.The tricky thing about dealing with errors in data-access programming is that so many things can go wrong at various stages in each request. The programmer can phrase the command in a syntactically incorrect way; the network connection can be bad; the database server can be on vacation. So it's useful in database programming to have a rich collection of error messages from every element in every database call.ADO.old provided this in the form of an Errors collection associated with the database connection object. In ADO.NET, you are given a provider-specific exception object that contains a collection of error messages. Again, the functionality is similar to ADO.old; the only difference is in the implementation details.In the SQL Server provider, a SqlException object is thrown whenever a data-access operation fails. This object contains a collection of SqlError objects that you can examine in code to determine the full extent of what went wrong with your database call.If you're interested only in determining whether a particular data-access operation succeeded or failed, you need only catch the top-level error. To get a brief error message pertaining to the error, use the Message property of the SqlException object. On the other hand, if you want complete and detailed information about what went wrong, you must iterate through the SqlError objects contained in the SqlException object (these are exposed through the SqlException object's Errors collection).Listing 11.22 shows an example of the simple method of displaying a SQL error.
Listing 11.22 Displaying a Data-Access Error
<% @Page language='c#' debug='true' %>
<% @Import namespace='System.Data' %>
<% @Import namespace='System.Data.SqlClient' %>
<HTML>
<SCRIPT runat='server'>
void Page_Load(Object Sender,EventArgs e)
{
SqlConnection cn;
SqlDataAdapter da;
DataSet ds;
String strSQL;
strSQL = "SELECT TOP 10 au_fname FROM authors" ;
cn = new SqlConnection("server=localhost;uid=sa;pwd=;database=pubs;");
da = new SqlDataAdapter(strSQL, cn);
// ** Fill DataSet
ds = new DataSet();
da.Fill(ds, "Authors");
// ** Display data
DataGrid1.DataSource = ds.Tables["Authors"].DefaultView;
DataGrid1.DataBind();
}
</SCRIPT>
<BODY>
<ASP:datagrid id='DataGrid1' runat='server' />
</BODY>
</HTML>
This code intentionally contains an error (the SQL command contains a reference to a field that doesn't exist). To show how the code runs without the error condition, fix the SQL command (the string "SELECT * from authors" will work).Listing 11.23 provides an example of the more complete way of iterating through the Errors collection to display complete error information.
Listing 11.23 Using the Errors Collection to Display Rich Error Information
try
{
// ** Fill DataSet
ds = new DataSet();
da.Fill(ds, "Authors");
// ** Display data
DataGrid1.DataSource = ds.Tables["Authors"].DefaultView;
DataGrid1.DataBind();
}
catch(SqlException sx)
{
foreach(SqlError se in sx.Errors)
{
Response.Write("SQL Error: " + se.Message + "<BR>");
}
}
See the reference at the end of this chapter for more information on the properties and methods supported by the SqlError object. Also remember that SqlError is unique to the SQL Servermanaged provider in ADO.NET (if you're using the OLE DBmanaged provider, the analogous class is System.Data.OleDb.OleDbError).