From bde35369d32a727e7d2964ce401158f1df248cb8 Mon Sep 17 00:00:00 2001 From: Rob Knight Date: Wed, 30 Jul 2025 20:21:39 +0100 Subject: [PATCH] Return an error instead of panicking when too many statements (#372) * Return an error instead of panicking when too many statements * Improve clarity of variable names and error message --- src/frontend/error.rs | 10 ++++++++++ src/frontend/mod.rs | 29 ++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/frontend/error.rs b/src/frontend/error.rs index 6bdae2e..691eb36 100644 --- a/src/frontend/error.rs +++ b/src/frontend/error.rs @@ -35,6 +35,10 @@ pub enum InnerError { PodlangParse(String), #[error("POD Request validation error: {0}")] PodRequestValidation(String), + #[error("Too many public statements provided: {0} were provided, but the maximum is {1}")] + TooManyPublicStatements(usize, usize), + #[error("Too many statements provided: {0} were provided, but the maximum is {1}")] + TooManyStatements(usize, usize), // Other #[error("{0}")] Custom(String), @@ -104,4 +108,10 @@ impl Error { pub(crate) fn pod_request_validation(e: String) -> Self { new!(PodRequestValidation(e)) } + pub(crate) fn too_many_public_statements(found: usize, max: usize) -> Self { + new!(TooManyPublicStatements(found, max)) + } + pub(crate) fn too_many_statements(found: usize, max: usize) -> Self { + new!(TooManyStatements(found, max)) + } } diff --git a/src/frontend/mod.rs b/src/frontend/mod.rs index 5b7ffed..8cafce8 100644 --- a/src/frontend/mod.rs +++ b/src/frontend/mod.rs @@ -172,20 +172,27 @@ impl MainPodBuilder { pub fn add_recursive_pod(&mut self, pod: MainPod) { self.input_recursive_pods.push(pod); } - pub fn insert(&mut self, public: bool, st_op: (Statement, Operation)) { + pub fn insert(&mut self, public: bool, st_op: (Statement, Operation)) -> Result<()> { // TODO: Do error handling instead of panic let (st, op) = st_op; if public { self.public_statements.push(st.clone()); } if self.public_statements.len() > self.params.max_public_statements { - panic!("too many public statements"); + return Err(Error::too_many_public_statements( + self.public_statements.len(), + self.params.max_public_statements, + )); } self.statements.push(st); self.operations.push(op); if self.statements.len() > self.params.max_statements { - panic!("too many statements"); + return Err(Error::too_many_statements( + self.statements.len(), + self.params.max_statements, + )); } + Ok(()) } pub fn pub_op(&mut self, op: Operation) -> Result { @@ -511,7 +518,7 @@ impl MainPodBuilder { fn op(&mut self, public: bool, op: Operation) -> Result { let op = Self::fill_in_aux(Self::lower_op(op)?)?; let st = self.op_statement(op.clone())?; - self.insert(public, (st, op)); + self.insert(public, (st, op))?; Ok(self.statements[self.statements.len() - 1].clone()) } @@ -1273,10 +1280,10 @@ pub mod tests { vec![], OperationAux::None, ); - builder.insert(false, (st, op_new_entry.clone())); + builder.insert(false, (st, op_new_entry.clone())).unwrap(); let st = Statement::equal(AnchoredKey::from((SELF, "a")), Value::from(28)); - builder.insert(false, (st, op_new_entry.clone())); + builder.insert(false, (st, op_new_entry.clone())).unwrap(); let prover = MockProver {}; let pod = builder.prove(&prover).unwrap(); @@ -1301,8 +1308,12 @@ pub mod tests { vec![], OperationAux::None, ); - builder.insert(false, (value_of_a.clone(), op_new_entry.clone())); - builder.insert(false, (value_of_b.clone(), op_new_entry)); + builder + .insert(false, (value_of_a.clone(), op_new_entry.clone())) + .unwrap(); + builder + .insert(false, (value_of_b.clone(), op_new_entry)) + .unwrap(); let st = Statement::equal(self_a, self_b); let op = Operation( OperationType::Native(NativeOperation::EqualFromEntries), @@ -1312,7 +1323,7 @@ pub mod tests { ], OperationAux::None, ); - builder.insert(false, (st, op)); + builder.insert(false, (st, op)).unwrap(); let prover = MockProver {}; let pod = builder.prove(&prover).unwrap();