views:

356

answers:

1

i'm trying to trap a "timeout expired" error from ADO.

When a timeout happens, ADO returns:

Number:      0x80040E31 (DB_E_ABORTLIMITREACHED in oledberr.h)
SQLState:    HYT00
NativeError: 0

The NativeError of zero makes sense, since the timeout is not a function of the database engine (i.e. SQL Server), but of ADO's internal timeout mechanism.


The Number (i.e. the COM hresult) looks useful, but the definition of DB_E_ABORTLIMITREACHED in oledberr.h says:

Execution stopped because a resource limit was reached. No results were returned.

This error could apply to things besides "timeout expired" (some potentially server-side), such as a governor that limits:

  • CPU usage
  • I/O reads/writes
  • network bandwidth

and stops a query.


The final useful piece is SQLState, which is a database-independent error code system. Unfortunately the only reference for SQLState error codes i can find have no mention of HYT00.

What to do? What do do?


Note: i can't trust

0x80040E31 (DB_E_ABORTLIMITREACHED)

to mean "timeout expired", anymore than i could trust

0x80004005 (E_UNSPECIFIED_ERROR)

to mean "Transaction was deadlocked on lock resources with another process and has been chosen as the deadlock victim".


My pseudo-question becomes: does anyone have documentation on what the SQLState "HYT000" means?

And my real question still remains: How can i specifically trap an ADO timeout expired exception thrown by ADO?

Gotta love the questions where the developer is trying to "do the right thing", but nobody knows how to do the right thing. Also gotta love how googling for DB_E_ABORTLIMITREACHED and this question is #9, with MSDN nowhere to be found.

Update 3

From the OLEdb ICommand.Execute reference:

DB_E_ABORTLIMITREACHED

Execution has been aborted because a resource limit has been reached. For example, a query timed out. No results have been returned.

"For example", meaning not an exhaustive list.


Update Three

Found it. If you've read this far down then you can get free credit for an answer. Just copy and paste:


You can safely use HYT00 to mean "Timeout expired". The following comes from Microsoft's SQLSTATEs reference. It mentions the HYT00 SQLSTATE:

The following SQLSTATEs indicate run-time errors or warnings and are good candidates on which to base programming logic. However, there is no guarantee that all drivers return them.

01004 (Data truncated)

01S02 (Option value changed)

HY008 (Operation canceled)

HYC00 (Optional feature not implemented)

HYT00 (Timeout expired)

Which then links to Appendix A: ODBC Error Codes of the ODBC Programmer's Reference, which documents the SQLSTATE values:

  • HYT00 Timeout expired, and interestingly also
  • HYT01 Connection timeout expired

So you can use HYT00 for "Timeout expired".


A: 

Is it not just -2 or is it too obvious?

You can generate this in both SSMS and from Ado.net and we use this to decide whether to retry.

Old SO Question and a link and MSDN

gbn
Where are you getting `-2` from? Nothing is returning -2. The HRESULT from the call to the ADO COM object is `0x80040E31`. After the failed HRESULT, the `Connection` object's `Errors` collection contains one error, with a `SQLState` of `"HYT00"` and `NativeError` of `0`.
Ian Boyd
We get -2 in several places in .net and SSMS. And so do lots of other people as per my links. What exactly are you doing at what level? you mention ADO, COM, ODBC and SQL Server
gbn
`hresult = connection.Execute(commandText, recordsAffected, adExecuteNoRecords);` hresult will contain `0x80040E31`. `connection.Errors` collection will contain members, with the `SQLState` being `"HYT00"`, and `NativeError` being 0. You're confusing `ADO` (native COM objects) with `ADO.net` (.NET managed objects)
Ian Boyd
In my case `-2` is not obvious at all. Not only do i not have -2 returned to me, but it seems no more correct that -42 (which i also don't receive)
Ian Boyd