How to catch SQLServer timeout exceptions

109,289

Solution 1

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");
    }
}

Solution 2

here: http://www.tech-archive.net/Archive/DotNet/microsoft.public.dotnet.framework.adonet/2006-10/msg00064.html

You can read also that Thomas Weingartner wrote:

Timeout: SqlException.Number == -2 (This is an ADO.NET error code)
General Network Error: SqlException.Number == 11
Deadlock: SqlException.Number == 1205 (This is an SQL Server error code)

...

We handle the "General Network Error" as a timeout exception too. It only occurs under rare circumstances e.g. when your update/insert/delete query will raise a long running trigger.

Solution 3

Updated for c# 6:

    try
    {
        // some code
    }
    catch (SqlException ex) when (ex.Number == -2)  // -2 is a sql timeout
    {
        // handle timeout
    }

Very simple and nice to look at!!

Share:
109,289
brodie
Author by

brodie

Co-founder and Technical Director of Bravo - a nimble digital product design studio, creating things that are a joy to use, and serve real purpose for our clients and their customers.

Updated on December 25, 2020

Comments

  • brodie
    brodie over 3 years

    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;
        }
    }
    
  • brodie
    brodie over 15 years
    Yes, that's pretty much what I'm doing at the moment, but it's not very elegant checking for -2
  • Jonathan
    Jonathan over 15 years
    Download Red Gate's Reflector, and search for TIMEOUT_EXPIRED. It lives in System.Data.SqlClient.TdsEnums, and its value is -2. :o)
  • Eric Tuttleman
    Eric Tuttleman almost 14 years
    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.
  • codekaizen
    codekaizen over 12 years
    @Eric is correct - that is an HRESULT code for the SqlException type, not for the source of the exception.
  • ankitk
    ankitk over 10 years
    For those who do not have access to Reflector: link
  • Jason L.
    Jason L. about 7 years
    @brodie That's why you should make a constant for it and you can explain where the "magic" value came from in a comment on the constant.
  • Jonathan
    Jonathan over 4 years
    It does not answer the question which is how to catch a command timeout in the c# code
  • Rubens
    Rubens about 3 years
    Thanks... I like your suggestion and use it.