Skip to content

Conversation

@silver-ymz
Copy link
Contributor

@silver-ymz silver-ymz commented Dec 12, 2025

I hereby agree to the terms of the RisingWave Labs, Inc. Contributor License Agreement.

What's changed and what's your intention?

This PR improves error handling in the DataFusion integration.

  1. Adding backtrace support to DataFusion errors by enabling the "backtrace" feature for DataFusion dependencies
  2. When converting RisingWaveError to DataFusionError, it will embed backtrace to formated string like other datafusion errors.

Checklist

  • I have written necessary rustdoc comments.
  • I have added necessary unit tests and integration tests.
  • I have added test labels as necessary.
  • I have added fuzzing tests or opened an issue to track them.
  • My PR contains breaking changes.
  • My PR changes performance-critical code, so I will run (micro) benchmarks and present the results.
  • I have checked the Release Timeline and Currently Supported Versions to determine which release branches I need to cherry-pick this PR into.

Documentation

  • My PR needs documentation updates.
Release note

Copy link
Contributor Author

silver-ymz commented Dec 12, 2025

@silver-ymz silver-ymz marked this pull request as ready for review December 12, 2025 07:50
Copilot AI review requested due to automatic review settings December 12, 2025 07:50
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors error handling in the DataFusion integration by introducing a dedicated error module with proper backtrace support. The changes enable better debugging capabilities by capturing and formatting backtraces when converting RisingWave errors to DataFusion errors.

Key changes:

  • Creates a new error module with to_datafusion_error function that captures backtraces
  • Enables the "backtrace" feature for DataFusion dependencies to support backtrace functionality
  • Replaces the previous inline boxed helper function with the new centralized error conversion

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/frontend/src/datafusion/error.rs New module containing error wrapper struct and to_datafusion_error function with backtrace capture logic
src/frontend/src/datafusion/mod.rs Adds error module declaration and exports to_datafusion_error function, removes inline error conversion
src/frontend/src/datafusion/function.rs Replaces all boxed calls with to_datafusion_error and removes old helper function
src/frontend/src/datafusion/iceberg_executor.rs Updates to use exec_err! macro for more idiomatic DataFusion error handling
src/frontend/src/datafusion/iceberg_table_provider.rs Simplifies return type using DFResult type alias for consistency
src/frontend/Cargo.toml Enables "backtrace" features for datafusion dependencies and includes some unrelated formatting changes

@silver-ymz silver-ymz force-pushed the refactor/datafusion-error-handling branch 3 times, most recently from 97eb01c to dfffbcc Compare December 12, 2025 08:13
Base automatically changed from feat/datafusion-delete-scan to main December 12, 2025 09:08
@silver-ymz silver-ymz force-pushed the refactor/datafusion-error-handling branch from dfffbcc to 09e6d61 Compare December 12, 2025 09:17
Copy link
Contributor

@chenzl25 chenzl25 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Member

@BugenZhao BugenZhao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DataFusion's printing backtrace in Display impl is not a good practice in my own opinion. It's still okay if DataFusionError will be the topmost type. However, if we wrap it back into an RwError, it will confuse our Report and result in very ugly user-facing error message.

Would you add some e2e test case demonstrating the UI?

Comment on lines 33 to 37
if let Some(bt) = std::error::request_ref::<Backtrace>(self.0.as_ref()) {
write!(f, "{}{}", DataFusionError::BACK_TRACE_SEP, bt)?;
} else if let Some(bt) = &self.1 {
write!(f, "{}{}", DataFusionError::BACK_TRACE_SEP, bt)?;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we provide backtrace from either source, so that we can unify the fmt impl here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in new commit

@silver-ymz
Copy link
Contributor Author

However, if we wrap it back into an RwError, it will confuse our Report and result in very ugly user-facing error message.

Below is the actual error users see today. It is admittedly ugly, but at the moment there is no clean way to log the detailed backtrace without also exposing it to the user-facing console.

We may need to wait error_generic_member_access stable(rust-lang/rust#99301). DataFusion does not use nightly Rust, so it cannot rely on Error::provide to cleanly separate a user-facing error message from internal diagnostic details like backtraces.

Detailed error info
dev=> select name::jsonb from t;
ERROR:  Failed to run the query

Caused by these errors (recent errors listed first):
  1: External error
  2: error while evaluating expression `str_parse('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')`

backtrace:    0: std::backtrace_rs::backtrace::libunwind::trace
             at /rustc/b925a865e2c9a0aefe5a2877863cb4df796f2eaf/library/std/src/../../backtrace/src/backtrace/libunwind.rs:117:9
   1: std::backtrace_rs::backtrace::trace_unsynchronized
             at /rustc/b925a865e2c9a0aefe5a2877863cb4df796f2eaf/library/std/src/../../backtrace/src/backtrace/mod.rs:66:14
   2: std::backtrace::Backtrace::create
             at /rustc/b925a865e2c9a0aefe5a2877863cb4df796f2eaf/library/std/src/backtrace.rs:331:13
   3: std::backtrace::Backtrace::capture
             at /rustc/b925a865e2c9a0aefe5a2877863cb4df796f2eaf/library/std/src/backtrace.rs:296:9
   4: risingwave_frontend::datafusion::error::to_datafusion_error
             at ./src/frontend/src/datafusion/error.rs:61:19
   5: core::ops::function::FnOnce::call_once
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5
   6: core::result::Result<T,E>::map_err
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/result.rs:961:27
   7: <risingwave_frontend::datafusion::function::RwScalarFunction as datafusion_expr::udf::ScalarUDFImpl>::invoke_with_args
             at ./src/frontend/src/datafusion/function.rs:298:10
   8: datafusion_expr::udf::ScalarUDF::invoke_with_args
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/datafusion-expr-50.3.0/src/udf.rs:236:20
   9: <datafusion_physical_expr::scalar_function::ScalarFunctionExpr as datafusion_physical_expr_common::physical_expr::PhysicalExpr>::evaluate
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/datafusion-physical-expr-50.3.0/src/scalar_function.rs:278:31
  10: datafusion_physical_plan::projection::ProjectionStream::batch_project::{{closure}}
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/datafusion-physical-plan-50.3.0/src/projection.rs:432:22
  11: core::iter::adapters::map::map_try_fold::{{closure}}
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/map.rs:95:28
  12: core::iter::traits::iterator::Iterator::try_fold
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:2427:21
  13: <core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::try_fold
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/map.rs:121:19
  14: <core::iter::adapters::GenericShunt<I,R> as core::iter::traits::iterator::Iterator>::try_fold
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/mod.rs:192:14
  15: core::iter::traits::iterator::Iterator::try_for_each
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:2488:14
  16: <core::iter::adapters::GenericShunt<I,R> as core::iter::traits::iterator::Iterator>::next
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/mod.rs:174:14
  17: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/alloc/src/vec/spec_from_iter_nested.rs:24:41
  18: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/alloc/src/vec/spec_from_iter.rs:33:9
  19: <alloc::vec::Vec<T> as core::iter::traits::collect::FromIterator<T>>::from_iter
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/alloc/src/vec/mod.rs:3689:9
  20: core::iter::traits::iterator::Iterator::collect
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:2028:9
  21: <core::result::Result<V,E> as core::iter::traits::collect::FromIterator<core::result::Result<A,E>>>::from_iter::{{closure}}
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/result.rs:2144:51
  22: core::iter::adapters::try_process
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/adapters/mod.rs:160:17
  23: <core::result::Result<V,E> as core::iter::traits::collect::FromIterator<core::result::Result<A,E>>>::from_iter
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/result.rs:2144:9
  24: core::iter::traits::iterator::Iterator::collect
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:2028:9
  25: datafusion_physical_plan::projection::ProjectionStream::batch_project
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/datafusion-physical-plan-50.3.0/src/projection.rs:435:14
  26: <datafusion_physical_plan::projection::ProjectionStream as futures_core::stream::Stream>::poll_next::{{closure}}
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/datafusion-physical-plan-50.3.0/src/projection.rs:464:42
  27: core::task::poll::Poll<T>::map
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/task/poll.rs:54:43
  28: <datafusion_physical_plan::projection::ProjectionStream as futures_core::stream::Stream>::poll_next
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/datafusion-physical-plan-50.3.0/src/projection.rs:463:51
  29: <core::pin::Pin<P> as futures_core::stream::Stream>::poll_next
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-core-0.3.31/src/stream.rs:130:33
  30: futures_util::stream::stream::StreamExt::poll_next_unpin
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-util-0.3.31/src/stream/stream/mod.rs:1638:24
  31: <futures_util::stream::stream::next::Next<St> as core::future::future::Future>::poll
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-util-0.3.31/src/stream/stream/next.rs:32:21
  32: datafusion_physical_plan::stream::RecordBatchReceiverStreamBuilder::run_input::{{closure}}
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/datafusion-physical-plan-50.3.0/src/stream.rs:345:50
  33: datafusion_common_runtime::trace_utils::trace_future::{{closure}}
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/datafusion-common-runtime-50.3.0/src/trace_utils.rs:137:29
  34: <core::pin::Pin<P> as core::future::future::Future>::poll
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/future/future.rs:133:9
  35: <futures_util::future::future::map::Map<Fut,F> as core::future::future::Future>::poll
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-util-0.3.31/src/future/future/map.rs:55:44
  36: <futures_util::future::future::Map<Fut,F> as core::future::future::Future>::poll
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-util-0.3.31/src/lib.rs:86:35
  37: <core::pin::Pin<P> as core::future::future::Future>::poll
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/future/future.rs:133:9
  38: <tracing::instrument::Instrumented<T> as core::future::future::Future>::poll
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tracing-0.1.41/src/instrument.rs:321:15
  39: tokio::runtime::task::core::Core<T,S>::poll::{{closure}}
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/task/core.rs:365:24
  40: tokio::loom::std::unsafe_cell::UnsafeCell<T>::with_mut
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/loom/std/unsafe_cell.rs:16:9
  41: tokio::runtime::task::core::Core<T,S>::poll
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/task/core.rs:354:30
  42: tokio::runtime::task::harness::poll_future::{{closure}}
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/task/harness.rs:535:30
  43: <core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/panic/unwind_safe.rs:274:9
  44: std::panicking::catch_unwind::do_call
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/panicking.rs:590:40
  45: ___rust_try
  46: std::panicking::catch_unwind
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/panicking.rs:553:19
  47: std::panic::catch_unwind
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/panic.rs:359:14
  48: tokio::runtime::task::harness::poll_future
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/task/harness.rs:523:18
  49: tokio::runtime::task::harness::Harness<T,S>::poll_inner
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/task/harness.rs:210:27
  50: tokio::runtime::task::harness::Harness<T,S>::poll
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/task/harness.rs:155:20
  51: tokio::runtime::task::raw::poll
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/task/raw.rs:325:13
  52: tokio::runtime::task::raw::RawTask::poll
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/task/raw.rs:255:18
  53: tokio::runtime::task::LocalNotified<S>::run
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/task/mod.rs:509:13
  54: tokio::runtime::scheduler::multi_thread::worker::Context::run_task::{{closure}}
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/scheduler/multi_thread/worker.rs:677:22
  55: tokio::task::coop::with_budget
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/task/coop/mod.rs:167:5
  56: tokio::task::coop::budget
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/task/coop/mod.rs:133:5
  57: tokio::runtime::scheduler::multi_thread::worker::Context::run_task
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/scheduler/multi_thread/worker.rs:591:9
  58: tokio::runtime::scheduler::multi_thread::worker::Context::run
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/scheduler/multi_thread/worker.rs:539:29
  59: tokio::runtime::scheduler::multi_thread::worker::run::{{closure}}::{{closure}}
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/scheduler/multi_thread/worker.rs:504:24
  60: tokio::runtime::context::scoped::Scoped<T>::set
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/context/scoped.rs:40:9
  61: tokio::runtime::context::set_scheduler::{{closure}}
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/context.rs:176:38
  62: std::thread::local::LocalKey<T>::try_with
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/thread/local.rs:508:12
  63: std::thread::local::LocalKey<T>::with
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/thread/local.rs:472:20
  64: tokio::runtime::context::set_scheduler
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/context.rs:176:17
  65: tokio::runtime::scheduler::multi_thread::worker::run::{{closure}}
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/scheduler/multi_thread/worker.rs:499:9
  66: tokio::runtime::context::runtime::enter_runtime
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/context/runtime.rs:65:16
  67: tokio::runtime::scheduler::multi_thread::worker::run
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/scheduler/multi_thread/worker.rs:491:5
  68: tokio::runtime::scheduler::multi_thread::worker::Launch::launch::{{closure}}
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/scheduler/multi_thread/worker.rs:457:45
  69: <tokio::runtime::blocking::task::BlockingTask<T> as core::future::future::Future>::poll
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/blocking/task.rs:42:21
  70: <tracing::instrument::Instrumented<T> as core::future::future::Future>::poll
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tracing-0.1.41/src/instrument.rs:321:15
  71: tokio::runtime::task::core::Core<T,S>::poll::{{closure}}
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/task/core.rs:365:24
  72: tokio::loom::std::unsafe_cell::UnsafeCell<T>::with_mut
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/loom/std/unsafe_cell.rs:16:9
  73: tokio::runtime::task::core::Core<T,S>::poll
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/task/core.rs:354:30
  74: tokio::runtime::task::harness::poll_future::{{closure}}
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/task/harness.rs:535:30
  75: <core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/panic/unwind_safe.rs:274:9
  76: std::panicking::catch_unwind::do_call
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/panicking.rs:590:40
  77: ___rust_try
  78: std::panicking::catch_unwind
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/panicking.rs:553:19
  79: std::panic::catch_unwind
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/panic.rs:359:14
  80: tokio::runtime::task::harness::poll_future
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/task/harness.rs:523:18
  81: tokio::runtime::task::harness::Harness<T,S>::poll_inner
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/task/harness.rs:210:27
  82: tokio::runtime::task::harness::Harness<T,S>::poll
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/task/harness.rs:155:20
  83: tokio::runtime::task::raw::poll
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/task/raw.rs:325:13
  84: tokio::runtime::task::raw::RawTask::poll
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/task/raw.rs:255:18
  85: tokio::runtime::task::UnownedTask<S>::run
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/task/mod.rs:546:13
  86: tokio::runtime::blocking::pool::Task::run
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/blocking/pool.rs:161:19
  87: tokio::runtime::blocking::pool::Inner::run
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/blocking/pool.rs:516:22
  88: tokio::runtime::blocking::pool::Spawner::spawn_thread::{{closure}}
             at /Users/silver/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.2/src/runtime/blocking/pool.rs:474:47
  89: std::sys::backtrace::__rust_begin_short_backtrace
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/sys/backtrace.rs:158:18
  90: std::thread::Builder::spawn_unchecked_::{{closure}}::{{closure}}
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/thread/mod.rs:562:17
  91: <core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/panic/unwind_safe.rs:274:9
  92: std::panicking::catch_unwind::do_call
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/panicking.rs:590:40
  93: ___rust_try
  94: std::panicking::catch_unwind
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/panicking.rs:553:19
  95: std::panic::catch_unwind
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/panic.rs:359:14
  96: std::thread::Builder::spawn_unchecked_::{{closure}}
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/std/src/thread/mod.rs:560:30
  97: core::ops::function::FnOnce::call_once{{vtable.shim}}
             at /Users/silver/.rustup/toolchains/nightly-2025-10-10-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5
  98: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once
             at /rustc/b925a865e2c9a0aefe5a2877863cb4df796f2eaf/library/alloc/src/boxed.rs:2004:9
  99: std::sys::thread::unix::Thread::new::thread_start
             at /rustc/b925a865e2c9a0aefe5a2877863cb4df796f2eaf/library/std/src/sys/thread/unix.rs:126:17
 100: __pthread_cond_wait
  3: Parse error: jsonb expected value at line 1 column 1

@BugenZhao
Copy link
Member

Below is the actual error users see today. It is admittedly ugly, but at the moment there is no clean way to log the detailed backtrace without also exposing it to the user-facing console.

Actually we would like to refrain from printing backtrace to users via SQL interface. 😕

If embedding a backtrace is mainly for debugging purposes at current stage, then we may temporarily tolerate such user interface. However, if the motivation is to expose the backtrace to users, I don't think it's a good idea.

@silver-ymz
Copy link
Contributor Author

Actually we would like to refrain from printing backtrace to users via SQL interface. 😕

I agree with it.

Ideally, we would only emit the backtrace to logs for debugging purposes and keep the SQL user-facing error concise and clean. Unfortunately, with the current technical constraints, we don’t have a reliable way to separate the two.

Given that limitation, if we have to choose between losing the backtrace entirely or tolerating a somewhat ugly error message, I think keeping the backtrace is the lesser evil. It significantly improves debuggability, even though the user experience is not ideal.

This is not meant to justify exposing backtraces to users long-term. Once we have a proper mechanism to decouple logging from user-facing errors, we should absolutely switch to that.

@silver-ymz
Copy link
Contributor Author

Would you add some e2e test case demonstrating the UI?

Done in new commit

Copy link
Member

@BugenZhao BugenZhao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@silver-ymz silver-ymz added this pull request to the merge queue Dec 16, 2025
Merged via the queue into main with commit fd3bbdb Dec 16, 2025
36 checks passed
@silver-ymz silver-ymz deleted the refactor/datafusion-error-handling branch December 16, 2025 11:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants