risingwavelabs/risingwave · error · MetaError

anyhow!(err)

Error message

anyhow!(err)

What it means

Part of the From<sea_orm::DbErr> for MetaError conversion: when the DbErr is a SQL-level error (constraint violation, syntax, etc., exposed via sql_err()), it is re-wrapped with anyhow! into MetaError. There is even a `// todo: refine the error transform` note — the wrap loses structure.

Solutions

  1. Inspect the inner SQL error message in MetaError to see the actual constraint/query that failed.
  2. Resolve the underlying DB condition (duplicate key, missing table/column, lock) rather than retrying blindly.
  3. Consider matching on the concrete sql_err variant upstream for better handling (aligns with the code's own 'refine the error transform' todo).

Example fix

// before
return anyhow!(err).into();
// after
return MetaError::internal(format!("meta store sql error: {err}")); // preserve variant info
Defensive patterns

Strategy: try-catch

Validate before calling

// Check constraint preconditions before insert, e.g. duplicate-key probe
if txn.exists_duplicate(job).await? { bail!("duplicate meta record"); }

Try / catch

match res {
    Err(e) if e.to_string().contains("constraint") => /* handle conflict */,
    Err(e) => return Err(e),
    Ok(v) => v,
}

Prevention

When it happens

Trigger: Any meta-store operation through sea_orm whose query fails at the SQL layer (unique constraint, foreign key, SQL syntax, locked table) is converted to MetaError via this From impl.

Common situations: Duplicate primary key on insert during concurrent DDL, schema drift between code and the SQL meta store, SQLite/Postgres lock contention.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


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

Appendix: source

Thrown at src/meta/src/controller/mod.rs:55

use crate::{MetaError, MetaResult, MetaStoreBackend};

pub mod catalog;
pub mod cluster;
pub mod fragment;
pub mod id;
pub mod rename;
pub mod scale;
pub mod session_params;
pub mod streaming_job;
pub mod system_param;
pub mod user;
pub mod utils;

// todo: refine the error transform.
impl From<sea_orm::DbErr> for MetaError {
    fn from(err: sea_orm::DbErr) -> Self {
        if let Some(err) = err.sql_err() {
            return anyhow!(err).into();
        }
        anyhow!(err).into()
    }
}

#[derive(Clone)]
pub struct SqlMetaStore {
    pub conn: DatabaseConnection,
    pub endpoint: String,
}

impl SqlMetaStore {
    /// Connect to the SQL meta store based on the given configuration.
    pub async fn connect(backend: MetaStoreBackend) -> MetaResult<Self> {
        const MAX_DURATION: Duration = Duration::new(u64::MAX / 4, 0);

        #[easy_ext::ext]
        impl ConnectOptions {

View on GitHub (pinned to 6469eb736d)