{"record":{"id":"cfb3781966eece98","repo":"linera-io/linera-protocol","slug":"expected-an-executionerror-got-chain-error","errorCode":null,"errorMessage":"Expected an `ExecutionError`. Got: {chain_error:#?}","messagePattern":"Expected an `ExecutionError`\\. Got: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"linera-core/src/worker.rs","lineNumber":538,"sourceCode":"            error => Self::ChainError(Box::new(error)),\n        }\n    }\n}\n\n#[cfg(with_testing)]\nimpl WorkerError {\n    /// Returns the inner [`ExecutionError`] in this error.\n    ///\n    /// # Panics\n    ///\n    /// If this is not caused by an [`ExecutionError`].\n    pub fn expect_execution_error(self, expected_context: ChainExecutionContext) -> ExecutionError {\n        let WorkerError::ChainError(chain_error) = self else {\n            panic!(\"Expected an `ExecutionError`. Got: {self:#?}\");\n        };\n\n        let ChainError::ExecutionError(execution_error, context) = *chain_error else {\n            panic!(\"Expected an `ExecutionError`. Got: {chain_error:#?}\");\n        };\n\n        assert_eq!(context, expected_context);\n\n        *execution_error\n    }\n}\n\ntype ChainWorkerArc<S> = Arc<tokio::sync::RwLock<ChainWorkerState<S>>>;\ntype ChainWorkerWeak<S> = std::sync::Weak<tokio::sync::RwLock<ChainWorkerState<S>>>;\ntype ChainWorkerFuture<S> = Shared<oneshot::Receiver<ChainWorkerWeak<S>>>;\n\n/// Each map entry is a `Shared<oneshot::Receiver<Weak<...>>>`:\n///\n/// - `peek()` returns `None` while a task is loading the worker from storage.\n/// - `peek()` returns `Some(Ok(weak))` once the worker is loaded.\n/// - `peek()` returns `Some(Err(_))` if loading failed (sender dropped).\n///","sourceCodeStart":520,"sourceCodeEnd":556,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-core/src/worker.rs#L520-L556","documentation":"The second stage of expect_execution_error: the WorkerError was a ChainError, but the inner chain error is not the ExecutionError variant (e.g. an arithmetic/validity error, a view error, or another ChainError kind). The panic prints the full chain_error debug so the actual variant is identifiable. A third assertion (context == expected_context) follows after this stage.","triggerScenarios":"In tests: the worker wrapped a non-execution ChainError — certificate validation failures, view/bucket errors, chain-state problems — where the test expected user-code execution to fail. The {chain_error:#?} output names the true variant.","commonSituations":"Tests asserting application-level execution failures that actually fail earlier at consensus/state level; changes in error taxonomy moving a case from ChainError::ExecutionError to a sibling variant; fixtures leaving the chain in a state that errors before operations run.","solutions":["Read the {chain_error:#?} dump and either match that variant directly or fix the fixture so execution actually reaches the failing operation.","Verify the expected ChainExecutionContext too — the following assert_eq!(context, expected_context) is a common next failure.","Prefer explicit matches on the expected error shape in tests instead of blanket expect_* helpers when the error layer is uncertain."],"exampleFix":"// before\nlet exec = err.expect_execution_error(ChainExecutionContext::Query); // panics on ChainError::ArithError\n\n// after\nlet WorkerError::ChainError(chain_err) = err else { panic!(\"expected chain error\") };\nmatch *chain_err {\n    ChainError::ExecutionError(exec, ctx) => { assert_eq!(ctx, ChainExecutionContext::Query); /* ... */ }\n    other => panic!(\"unexpected: {other:?}\"),\n}","handlingStrategy":"type-guard","validationCode":"// Rust\nif !matches!(&err, WorkerError::ChainError(inner) if matches!(**inner, ChainError::ExecutionError(_, _))) {\n    // handle the actual chain error variant instead of unwrapping\n}","typeGuard":"fn chain_error_is_execution(err: &WorkerError) -> bool {\n    matches!(err, WorkerError::ChainError(inner) if matches!(&**inner, ChainError::ExecutionError(..)))\n}","tryCatchPattern":"let WorkerError::ChainError(chain_err) = err else { panic!(\"expected chain error\") };\nmatch *chain_err {\n    ChainError::ExecutionError(exec, ctx) => { assert_eq!(ctx, expected_ctx); /* assert on exec */ }\n    other => panic!(\"unexpected chain error: {other:?}\"),\n}","preventionTips":["Read the {chain_error:#?} dump in the panic — it names the true variant.","Also verify the ChainExecutionContext you pass matches where the error is actually raised (the next assert).","Keep test fixtures' chain state valid so errors surface at the execution layer you intend to assert on."],"tags":["rust","testing","worker-error","chain-error"],"backgroundTag":"unexpected-error-variant","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}