You think it would be easy to find information on exactly what error number a SqlException has when the command timed out. But, it isn’t. MSDN, for all that it is normally an excellent resource, fails to even mention that the Number property of a SqlException or SqlError can even be negative. (I suppose if I am to be fair, it doesn’t say it can be positive either). What it does say is exactly this:
This number corresponds to an entry in the master.dbo.sysmessages table.[^]
If you look at the sysmessages table, you will notice that all the numbers are positive. So, why am I concerned about negative numbers? Because sometimes the SqlException.Number property returns negative numbers, and therefore it does not correspond to an entry in the sysmessages table. So, the documentation is not telling the whole story.
I want to find out when an SqlException happened because of a timeout. The easiest, and I should imagine, the more reliable way of checking a SqlException for any particular error message is to check the Number property in case the message description has been localised or changed for some other reason. For most cases this is perfectly fine. I can check the sysmessages table for the description for the error that I am wanting to handle and I can check for that number when I catch a SqlException. But, there isn’t any error number for a timeout.
The exact error message that is in the SqlException is
Error: System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
So, if the error is potentially because the server isn’t responding then the error message cannot be generated on SQL Server itself. How would it generate this error message if the server isn’t responding? The error, I can only assume, is being generated by ADO.NET. Why do I say I can only assume? Because after spending some time fruitlessly googling for a definitive answer I have yet to find one.
The best answer I’ve found is some sample code, that happens to check the Number property of the SqlException in a switch statement and next to case -2: is the comment /* Timeout */
So, at the moment I’m working on the assumption that -2 just means a timeout caused the execution of the SqlCommand to fail. I don’t like developing software in this way because if there is a bug in the future I cannot be certain that this code is okay or if sometimes -2 is something else, or perhaps sometime a timeout is something other than -2
NOTE: This was rescued from the Wayback Machine. The original date was Monday 17th October, 2005.
Tags: microsoft
sql server
sql
exception
timeout
.net
Original Comments:
-2 is the error code for timeout, returned from DBNETLIB, the MDAC driver for SQL Server. So, its not ADO.NET.
A full list of possible error numbers can be found by using Reflector on System.Data.SqlClient.TdsParser.ProcessNetLibError.
Steve: That is most helpful. I feel much more confident that my code is doing the right thing now. Many thanks.
This just came in handy for me, thanks.
Here, there is a list produced by reflection of System.Data.SqlClient.TdsParser.ProcessNetLibError:-3: ZeroBytes-2: Timeout-1: Unknown1: InsufficientMemory2: AccessDenied3: ConnectionBusy4: ConnectionBroken5: ConnectionLimit6: ServerNotFound7: NetworkNotFound8: InsufficientResources9: NetworkBusy10: NetworkAccessDenied11: GeneralError12: IncorrectMode13: NameNotFound14: InvalidConnection15: ReadWriteError16: TooManyHandles17: ServerError18: SSLError19: EncryptionError20: EncryptionNotSupported
Exception information: Exception type: SqlException Exception message: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.The statement has been terminated. Request information: Request URL: http://www…………….. Request path: http://www…………. Thread information: Thread ID: 5 Thread account name: NT AUTHORITYNETWORK SERVICE Is impersonating: False Stack trace: at clErr.HandleException(Exception ex, Page oPage) at vd_processing_reports_registration_count.btnReport_Click(Object sender, EventArgs e) at System.Web.UI.WebControls.Button.OnClick(EventArgs e) at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) at System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) if i re execute to the procedure than it works properly. plzzzz help me
@raman Possibly the first time you run it the query takes too long to fetch the data. The second time the data is retrieved from cache rather than disk so it can perform the query within the timeout period. Possibly.By the way, the best place to ask this sort of question is on a forum. Like CodeProject’s Database Forum