Skip to content

Commit 260e75f

Browse files
committed
fix: mangled errors
1 parent 8fc9436 commit 260e75f

4 files changed

Lines changed: 50 additions & 2 deletions

File tree

python/tests/test_catalog.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ def table_exist(self, name: str) -> bool:
8181
return name in self.tables
8282

8383

84+
class CustomErrorSchemaProvider(CustomSchemaProvider):
85+
def table(self, name: str) -> Table | None:
86+
message = f"{name} is not an acceptable name"
87+
raise ValueError(message)
88+
89+
8490
class CustomCatalogProvider(dfn.catalog.CatalogProvider):
8591
def __init__(self):
8692
self.schemas = {"my_schema": CustomSchemaProvider()}
@@ -197,6 +203,33 @@ def test_python_table_provider(ctx: SessionContext):
197203
assert schema.table_names() == {"table4"}
198204

199205

206+
def test_exception_not_mangled(ctx: SessionContext):
207+
"""Test registering all python providers and running a query against them."""
208+
209+
catalog_name = "custom_catalog"
210+
schema_name = "custom_schema"
211+
212+
ctx.register_catalog_provider(catalog_name, CustomCatalogProvider())
213+
214+
catalog = ctx.catalog(catalog_name)
215+
216+
# Clean out previous schemas if they exist so we can start clean
217+
for schema_name in catalog.schema_names():
218+
catalog.deregister_schema(schema_name, cascade=False)
219+
220+
catalog.register_schema(schema_name, CustomErrorSchemaProvider())
221+
222+
schema = catalog.schema(schema_name)
223+
224+
for table_name in schema.table_names():
225+
schema.deregister_table(table_name)
226+
227+
schema.register_table("test_table", create_dataset())
228+
229+
with pytest.raises(ValueError, match="^test_table is not an acceptable name$"):
230+
ctx.sql(f"select * from {catalog_name}.{schema_name}.test_table")
231+
232+
200233
def test_schema_register_table_with_pyarrow_dataset(ctx: SessionContext):
201234
schema = ctx.catalog().schema()
202235
batch = pa.RecordBatch.from_arrays(

python/tests/test_sql.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@
2929

3030

3131
def test_no_table(ctx):
32-
with pytest.raises(Exception, match="DataFusion error"):
32+
with pytest.raises(
33+
ValueError,
34+
match="^Error during planning: table 'datafusion.public.b' not found$",
35+
):
3336
ctx.sql("SELECT a FROM b").collect()
3437

3538

src/catalog.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,8 @@ impl SchemaProvider for RustWrappedPySchemaProvider {
364364
&self,
365365
name: &str,
366366
) -> datafusion::common::Result<Option<Arc<dyn TableProvider>>, DataFusionError> {
367-
self.table_inner(name).map_err(to_datafusion_err)
367+
self.table_inner(name)
368+
.map_err(|e| DataFusionError::External(Box::new(e)))
368369
}
369370

370371
fn register_table(

src/errors.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use std::fmt::Debug;
2222
use datafusion::arrow::error::ArrowError;
2323
use datafusion::error::DataFusionError as InnerDataFusionError;
2424
use prost::EncodeError;
25+
use pyo3::exceptions::PyValueError;
2526
use pyo3::exceptions::PyException;
2627
use pyo3::PyErr;
2728

@@ -96,3 +97,13 @@ pub fn py_unsupported_variant_err(e: impl Debug) -> PyErr {
9697
pub fn to_datafusion_err(e: impl Debug) -> InnerDataFusionError {
9798
InnerDataFusionError::Execution(format!("{e:?}"))
9899
}
100+
101+
pub fn from_datafusion_error(err: InnerDataFusionError) -> PyErr {
102+
match err {
103+
InnerDataFusionError::External(boxed) => match boxed.downcast::<PyErr>() {
104+
Ok(py_err) => *py_err,
105+
Err(original_boxed) => PyValueError::new_err(format!("{original_boxed}")),
106+
},
107+
_ => PyValueError::new_err(format!("{err}")),
108+
}
109+
}

0 commit comments

Comments
 (0)