single-cell-data / TileDB-SOMA

Python and R SOMA APIs using TileDB’s cloud-native format. Ideal for single-cell data at any scale.
https://tiledbsoma.readthedocs.io
MIT License
90 stars 25 forks source link

[python] `SOMAError` error/exception messages need refinement #2298

Open bkmartinjr opened 7 months ago

bkmartinjr commented 7 months ago

As we migrate to more C++ shared code in tiledbsoma, the error handling is changing and could use some UX refinement to make error messages easier to understand.

Example: I used a value filter on a DataFrame, but had the typing wrong in the condition. The resulting exception was quite confusing, and really didn't point me in the right direction.

Running on a 1.9 pre-release (main branch). The root cause of the exception below is giving the in operator integer values for a string column. But the error message create_string(): incompatible function arguments was quite confusing....

# A is an open SOMADataFrame
In [26]: A
Out[26]: <DataFrame 'test_dataframe' (open for 'r')>

In [27]: A.schema
Out[27]: 
soma_joinid: int64 not null
A: dictionary<values=string, indices=int8, ordered=0> not null

In [28]: A.read(value_filter="A in [0,1]")
---------------------------------------------------------------------------
SOMAError                                 Traceback (most recent call last)
Cell In[28], line 1
----> 1 A.read(value_filter="A in [0,1]")

File ~/cellxgene-census/venv311/lib/python3.11/site-packages/tiledbsoma/_dataframe.py:361, in DataFrame.read(***failed resolving arguments***)
    351 sr = clib.SOMADataFrame.open(
    352     uri=handle.uri,
    353     mode=clib.OpenMode.read,
   (...)
    357     timestamp=handle.timestamp and (0, handle.timestamp),
    358 )
    360 if value_filter is not None:
--> 361     sr.set_condition(QueryCondition(value_filter), handle.schema)
    363 self._set_reader_coords(sr, coords)
    365 # # TODO: batch_size

SOMAError: SOMAError: create_string(): incompatible function arguments. The following argument types are supported:
    1. (arg0: str, arg1: List[str], arg2: tiledb_query_condition_op_t) -> tiledbsoma.pytiledbsoma.PyQueryCondition

Invoked with: 'A', [0, 1], <tiledb_query_condition_op_t.TILEDB_IN: 6>

At:
  /home/bruce/cellxgene-census/venv311/lib/python3.11/site-packages/tiledbsoma/_query_condition.py(137): init_query_condition
  /home/bruce/cellxgene-census/venv311/lib/python3.11/site-packages/tiledbsoma/_dataframe.py(361): read
  <ipython-input-28-3be011ba60a7>(1): <module>
  /home/bruce/cellxgene-census/venv311/lib/python3.11/site-packages/IPython/core/interactiveshell.py(3550): run_code
  /home/bruce/cellxgene-census/venv311/lib/python3.11/site-packages/IPython/core/interactiveshell.py(3490): run_ast_nodes
  /home/bruce/cellxgene-census/venv311/lib/python3.11/site-packages/IPython/core/interactiveshell.py(3308): run_cell_async
  /home/bruce/cellxgene-census/venv311/lib/python3.11/site-packages/IPython/core/async_helpers.py(129): _pseudo_sync_runner
  /home/bruce/cellxgene-census/venv311/lib/python3.11/site-packages/IPython/core/interactiveshell.py(3103): _run_cell
  /home/bruce/cellxgene-census/venv311/lib/python3.11/site-packages/IPython/core/interactiveshell.py(3048): run_cell
  /home/bruce/cellxgene-census/venv311/lib/python3.11/site-packages/IPython/terminal/interactiveshell.py(880): interact
  /home/bruce/cellxgene-census/venv311/lib/python3.11/site-packages/IPython/terminal/interactiveshell.py(887): mainloop
  /home/bruce/cellxgene-census/venv311/lib/python3.11/site-packages/IPython/terminal/ipapp.py(317): start
  /home/bruce/cellxgene-census/venv311/lib/python3.11/site-packages/traitlets/config/application.py(1077): launch_instance
  /home/bruce/cellxgene-census/venv311/lib/python3.11/site-packages/IPython/__init__.py(129): start_ipython
  /home/bruce/cellxgene-census/venv311/bin/ipython(8): <module>
johnkerl commented 6 months ago

Primary pain point: