risingwavelabs/risingwave · error · ExprError

{0}

Error message

{0}

What it means

ExprError::Custom is a pass-through variant that surfaces an arbitrary error message verbatim, primarily used to propagate UDF (user-defined function) errors into the expression error type. The message content comes entirely from the caller, most often external UDF code. Nothing is added by the framework, so diagnosis depends on the UDF author's message.

Source

Thrown at src/expr/core/src/error.rs:124

    FieldNameNull,

    #[error("too few arguments for format()")]
    TooFewArguments,

    #[error(
        "null value in column \"{col_name}\" of relation \"{table_name}\" violates not-null constraint"
    )]
    NotNullViolation {
        col_name: Box<str>,
        table_name: Box<str>,
    },

    #[error("invalid state: {0}")]
    InvalidState(String),

    /// Function error message returned by UDF.
    /// TODO: replace with `Function`
    #[error("{0}")]
    Custom(String),

    /// Error from a function call.
    ///
    /// Use [`ExprError::function`] to create this error.
    #[error("error while evaluating expression `{display}`")]
    Function {
        display: Box<str>,
        #[backtrace]
        // We don't use `anyhow::Error` because we don't want to always capture the backtrace.
        source: Box<dyn std::error::Error + Send + Sync>,
    },
}

static_assertions::const_assert_eq!(std::mem::size_of::<ExprError>(), 40);

impl ExprError {
    /// Constructs a [`ExprError::Function`] error with the given information for display.

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Read the raw message — it originates from the UDF itself
  2. Fix the input data or arguments that caused the UDF to fail
  3. Check the UDF implementation/service logs for the underlying cause
  4. If the UDF is external, verify the UDF service is running and reachable
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate UDF inputs before calling
if !udf_inputs_valid(args) { return Err("invalid UDF args"); }

Try / catch

match result { Err(ExprError::Custom(msg)) => { log::error!("UDF failed: {msg}"); fallback_or_abort(msg) }, Ok(v) => v, Err(e) => return Err(e) }

Prevention

When it happens

Trigger: A UDF returns an error (e.g. via a failed external function call), and the UDF runtime wraps that error message into ExprError::Custom.

Common situations: Python/JavaScript/SQL UDFs raising exceptions or returning error strings; remote UDF services returning failure payloads; misconfigured UDF external servers.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/cd2f5923a060d273. Report an issue: GitHub.