CurtHagenlocher opened a new issue, #4982:
URL: https://github.com/apache/arrow-adbc/issues/4982
### What feature or improvement would you like to see?
When a C# driver exported through `CAdbcDriverExporter` fails partway
through reading a result stream, the error's `AdbcStatusCode`, vendor code and
SQLSTATE are lost at the C ABI. A native consumer can't tell a cancelled read
(`ADBC_STATUS_CANCELLED`) from a lost connection or a server error. Errors
returned before the stream is handed out are fine, because they go through the
normal `AdbcError` path.
**Where it's lost** (as of 2042317c2):
- **The exporter doesn't implement `AdbcErrorFromArrayStream` (ADBC 1.1).**
`CAdbcDriverExporter` leaves `ErrorFromArrayStream` null on purpose ("exported
streams report errors through ArrowArrayStream.get_last_error only").
- **The stream reports a generic error code.** Exported streams go through
Arrow's `CArrowArrayStreamExporter`, whose `get_next` returns `EOTHER` for
every exception, with the message in `get_last_error`. So even the errno
doesn't say "cancelled".
- **The importer never asks for the status.** `CAdbcDriverImporter` imports
result streams with Arrow's `CArrowArrayStreamImporter`, which throws a plain
`System.Exception(message)` when `get_next` fails, and its default
`ErrorFromArrayStream` returns null. So even a driver that implements
`ErrorFromArrayStream` (Go, C++) doesn't give a C# caller an `AdbcException`
with its status.
**How it shows up:** a SQL Server driver built on `CAdbcDriverExporter` and
published with NativeAOT raises `AdbcException` with `AdbcStatusCode.Cancelled`
when a read is cancelled. Loaded back through `CAdbcDriverImporter`, the read
fails with `System.Exception: The operation was cancelled`. Python's
`adbc_driver_manager` calls `AdbcErrorFromArrayStream` when a stream fails, so
it would map the error to the right exception class if the exporter provided it.
**What I'd propose:**
1. **Exporter:** keep the `AdbcException` from a failed `get_next` (and
`get_schema`) with the exported stream, and implement `ErrorFromArrayStream` to
return its status and an `AdbcError` with the message, vendor code, SQLSTATE
and, for the 1.1 layout, the details. This needs the stream exported by
`CAdbcDriverExporter` to be recognisable as its own, for example by wrapping
the Arrow-exported stream or exporting through an ADBC-owned stream.
2. **errno:** map statuses to errno values in `get_next`, as other drivers
do, for example `Cancelled` → `ECANCELED`, `Timeout` → `ETIMEDOUT`,
`InvalidArgument` → `EINVAL`, `NotImplemented` → `ENOSYS`, and `EIO` otherwise.
That helps consumers that only look at the errno.
3. **Importer:** when `get_next` fails, call the driver's
`ErrorFromArrayStream` and throw an `AdbcException` with the status and
details, falling back to the current message-only exception when it returns
null.
The cancel case is the clearest one, since callers often need to tell "I
cancelled this" from "this failed". The same applies to any error raised
mid-read, such as a lost connection or a server error after the first rows.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]