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]

Reply via email to