views:

3897

answers:

4

I need to specifically catch SQL server timeout exceptions so that they can be handled differently. I know I could catch the SqlException and then check if the message string Contains "Timeout" but was wondering if there is a better way to do it?

try
{
    //some code
}
catch (SqlException ex)
{

    if (ex.Message.Contains("Timeout"))
    {
         //handle timeout
    }
    else
    {
         throw;
    }
}
+1  A: 

Whats the value for the SqlException.ErrorCode property? Can you work with that?

Seems like this guy is having timeouts, may be worth checking the code for -2146232060.

I would set this up as a static const in your data code.

Rob Cooper
Looking at the docs for ErrorCode, it seems to me that it's reporting Interop-Level errors. So it may be more on the level of COM errors or that a provider encountered an exception (generally) instead of a specific error relating to what you're doing.
Eric Tuttleman
A: 

I searched through our error log files for previous occurrences of ErrorCode -2146232060 and found several instances where it does not relate to a timeout error. The error code also occurs for data conversion errors and deadlock errors.

I noticed that the exception provides another 'Number' field which seems to always be set to '2' for timeout errors. I guess I'll just check both the ErrorCode and Number properties rather than do a Contains("Timeout") on the Message property.

But I can't find any documentation out there about these magic numbers ... if anyone has a link it'd be appreciated.

brodie
The MSDN docs say that the values in the Number field come from the sysmessages table in the master database. That might be your best bet for an authoritative source.
Charlie
A: 

Are you looking for a ConnectionTimeout or a CommandTimeout, ie are you expecting the connection to fail or the executed command to fail?

edosoft
I'm looking for a CommandTimeout, which is set to a default of 30 secs i think
brodie
+12  A: 

To check for a timeout, I believe you check the value of ex.Number. If it is -2, then you have a timeout situation.

-2 is the error code for timeout, returned from DBNETLIB, the MDAC driver for SQL Server. This can be seen by downloading Reflector, and looking under System.Data.SqlClient.TdsEnums for TIMEOUT_EXPIRED.

Your code would read:

if (ex.Number == -2)
{
     //handle timeout
}

Code to demonstrate failure:

try
{
    SqlConnection sql = new SqlConnection(@"Network Library=DBMSSOCN;Data Source=YourServer,1433;Initial Catalog=YourDB;Integrated Security=SSPI;");
    sql.Open();

    SqlCommand cmd = sql.CreateCommand();
    cmd.CommandText = "DECLARE @i int WHILE EXISTS (SELECT 1 from sysobjects) BEGIN SELECT @i = 1 END";
    cmd.ExecuteNonQuery(); // This line will timeout.

    cmd.Dispose();
    sql.Close();
}
catch (SqlException ex)
{
    if (ex.Number == -2) {
        Console.WriteLine ("Timeout occurred");
}
Jonathan
Yes, that's pretty much what I'm doing at the moment, but it's not very elegant checking for -2
brodie
Download Red Gate's Reflector, and search for TIMEOUT_EXPIRED. It lives in System.Data.SqlClient.TdsEnums, and its value is -2. :o)
Jonathan