Merge 'Simulator: show inner error if any' from Jussi Saurio

Seed 16184573510628167771 in git hash 7c549bc produces a missing row
error, but the underlying error is `Parse error: table
breathtaking_dimitrakis not found`, which was not obvious without
exposing the error in the message the simulator prints on assertion
failure.
This PR just exposes the inner error, if any.

Closes #704
This commit is contained in:
Pekka Enberg
2025-01-15 19:45:49 +02:00
2 changed files with 27 additions and 17 deletions

View File

@@ -167,7 +167,7 @@ impl Display for Interaction {
}
}
type AssertionFunc = dyn Fn(&Vec<ResultSet>, &SimulatorEnv) -> bool;
type AssertionFunc = dyn Fn(&Vec<ResultSet>, &SimulatorEnv) -> Result<bool>;
enum AssertionAST {
Pick(),
@@ -375,12 +375,17 @@ impl Interaction {
unreachable!("unexpected: this function should only be called on assertions")
}
Self::Assertion(assertion) => {
if !assertion.func.as_ref()(stack, env) {
return Err(limbo_core::LimboError::InternalError(
let result = assertion.func.as_ref()(stack, env);
match result {
Ok(true) => Ok(()),
Ok(false) => Err(limbo_core::LimboError::InternalError(
assertion.message.clone(),
));
)),
Err(err) => Err(limbo_core::LimboError::InternalError(format!(
"{}. Inner error: {}",
assertion.message, err
))),
}
Ok(())
}
Self::Assumption(_) => {
unreachable!("unexpected: this function should only be called on assertions")
@@ -404,12 +409,17 @@ impl Interaction {
unreachable!("unexpected: this function should only be called on assumptions")
}
Self::Assumption(assumption) => {
if !assumption.func.as_ref()(stack, env) {
return Err(limbo_core::LimboError::InternalError(
let result = assumption.func.as_ref()(stack, env);
match result {
Ok(true) => Ok(()),
Ok(false) => Err(limbo_core::LimboError::InternalError(
assumption.message.clone(),
));
)),
Err(err) => Err(limbo_core::LimboError::InternalError(format!(
"{}. Inner error: {}",
assumption.message, err
))),
}
Ok(())
}
Self::Fault(_) => {
unreachable!("unexpected: this function should only be called on assumptions")

View File

@@ -1,3 +1,5 @@
use limbo_core::LimboError;
use crate::{
model::{
query::{Create, Delete, Insert, Predicate, Query, Select},
@@ -94,7 +96,7 @@ impl Property {
func: Box::new({
let table_name = insert.table.clone();
move |_: &Vec<ResultSet>, env: &SimulatorEnv| {
env.tables.iter().any(|t| t.name == table_name)
Ok(env.tables.iter().any(|t| t.name == table_name))
}
}),
});
@@ -109,8 +111,8 @@ impl Property {
func: Box::new(move |stack: &Vec<ResultSet>, _: &SimulatorEnv| {
let rows = stack.last().unwrap();
match rows {
Ok(rows) => rows.iter().any(|r| r == &row),
Err(_) => false,
Ok(rows) => Ok(rows.iter().any(|r| r == &row)),
Err(err) => Err(LimboError::InternalError(err.to_string())),
}
}),
});
@@ -131,7 +133,7 @@ impl Property {
message: "Double-Create-Failure should not be called on an existing table"
.to_string(),
func: Box::new(move |_: &Vec<ResultSet>, env: &SimulatorEnv| {
!env.tables.iter().any(|t| t.name == table_name)
Ok(!env.tables.iter().any(|t| t.name == table_name))
}),
});
@@ -147,10 +149,8 @@ impl Property {
func: Box::new(move |stack: &Vec<ResultSet>, _: &SimulatorEnv| {
let last = stack.last().unwrap();
match last {
Ok(_) => false,
Err(e) => e
.to_string()
.contains(&format!("Table {table_name} already exists")),
Ok(_) => Ok(false),
Err(e) => Ok(e.to_string().contains(&format!("Table {table_name} already exists"))),
}
}),
});