migrate from anyhow to thiserror (#197)

* migrate from anyhow to thiserror (#190). pending polish error msgs

* Add backtrace and compartmentalize errors

- Include backtraces in the errors we generate.  To get this we can't
  just return a literal enum, because the backtrace requires a call.
- Related to the previous point: add methods to create errors so
  we can include the backtrace conveniently without changing too much
  the syntax.  So instead of `Err(Error::KeyNotFound(key))` (literal
  enum) it will be `Err(Error::key_not_found(key))` (method call)
- Each error should be local to its scope, and each scope should
  only return its own error.
  - The merkle tree should return `TreeError` and not Error
  - The middleware should return `MiddlewareError` and not Error
- With a global Error we can't easily include backend/frontend types in
  the error fields, so declare a `BackendError` and a `FrontendError`
  and follow the pattern from the previous point
- The Pod traits should be able to return backend errors and will be
  used in the frontend; for that we change them to use trait object
  Error: `dyn std::error::Error`

* fix error

* apply suggestions from @arnaucube

* rename XError and XResult to Error and Result

* reorg signature

* make frontend custom error more ergonomic

* remove unnecessary feature

---------

Co-authored-by: Eduard S. <eduardsanou@posteo.net>
This commit is contained in:
arnaucube 2025-04-22 15:07:04 +02:00 committed by GitHub
parent 58d3c6a236
commit 29545f03fc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
31 changed files with 696 additions and 273 deletions

View file

@ -1,14 +1,13 @@
use std::{fmt, iter};
use anyhow::{anyhow, Result};
use plonky2::field::types::Field;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use strum_macros::FromRepr;
use crate::middleware::{
AnchoredKey, CustomPredicateRef, Key, Params, PodId, Predicate, RawValue, ToFields, Value, F,
VALUE_SIZE,
AnchoredKey, CustomPredicateRef, Error, Key, Params, PodId, Predicate, RawValue, Result,
ToFields, Value, F, VALUE_SIZE,
};
// TODO: Maybe store KEY_SIGNER and KEY_TYPE as Key with lazy_static
@ -152,7 +151,7 @@ impl Statement {
{
Ok(Self::ValueOf(a0, v1))
} else {
Err(anyhow!("Incorrect statement args"))
Err(Error::incorrect_statements_args())
}
}
Native(NativePredicate::Equal) => {
@ -161,7 +160,7 @@ impl Statement {
{
Ok(Self::Equal(a0, a1))
} else {
Err(anyhow!("Incorrect statement args"))
Err(Error::incorrect_statements_args())
}
}
Native(NativePredicate::NotEqual) => {
@ -170,7 +169,7 @@ impl Statement {
{
Ok(Self::NotEqual(a0, a1))
} else {
Err(anyhow!("Incorrect statement args"))
Err(Error::incorrect_statements_args())
}
}
Native(NativePredicate::Gt) => {
@ -179,7 +178,7 @@ impl Statement {
{
Ok(Self::Gt(a0, a1))
} else {
Err(anyhow!("Incorrect statement args"))
Err(Error::incorrect_statements_args())
}
}
Native(NativePredicate::Lt) => {
@ -188,7 +187,7 @@ impl Statement {
{
Ok(Self::Lt(a0, a1))
} else {
Err(anyhow!("Incorrect statement args"))
Err(Error::incorrect_statements_args())
}
}
Native(NativePredicate::Contains) => {
@ -197,7 +196,7 @@ impl Statement {
{
Ok(Self::Contains(a0, a1, a2))
} else {
Err(anyhow!("Incorrect statement args"))
Err(Error::incorrect_statements_args())
}
}
Native(NativePredicate::NotContains) => {
@ -206,7 +205,7 @@ impl Statement {
{
Ok(Self::NotContains(a0, a1))
} else {
Err(anyhow!("Incorrect statement args"))
Err(Error::incorrect_statements_args())
}
}
Native(NativePredicate::SumOf) => {
@ -215,7 +214,7 @@ impl Statement {
{
Ok(Self::SumOf(a0, a1, a2))
} else {
Err(anyhow!("Incorrect statement args"))
Err(Error::incorrect_statements_args())
}
}
Native(NativePredicate::ProductOf) => {
@ -224,7 +223,7 @@ impl Statement {
{
Ok(Self::ProductOf(a0, a1, a2))
} else {
Err(anyhow!("Incorrect statement args"))
Err(Error::incorrect_statements_args())
}
}
Native(NativePredicate::MaxOf) => {
@ -233,17 +232,17 @@ impl Statement {
{
Ok(Self::MaxOf(a0, a1, a2))
} else {
Err(anyhow!("Incorrect statement args"))
Err(Error::incorrect_statements_args())
}
}
Native(np) => Err(anyhow!("Predicate {:?} is syntax sugar", np)),
Native(np) => Err(Error::custom(format!("Predicate {:?} is syntax sugar", np))),
BatchSelf(_) => unreachable!(),
Custom(cpr) => {
let v_args: Result<Vec<WildcardValue>> = args
.iter()
.map(|x| match x {
StatementArg::WildcardLiteral(v) => Ok(v.clone()),
_ => Err(anyhow!("Incorrect statement args")),
_ => Err(Error::incorrect_statements_args()),
})
.collect();
Ok(Self::Custom(cpr, v_args?))
@ -302,13 +301,19 @@ impl StatementArg {
pub fn literal(&self) -> Result<Value> {
match self {
Self::Literal(value) => Ok(value.clone()),
_ => Err(anyhow!("Statement argument {:?} is not a literal.", self)),
_ => Err(Error::invalid_statement_arg(
self.clone(),
"literal".to_string(),
)),
}
}
pub fn key(&self) -> Result<AnchoredKey> {
match self {
Self::Key(ak) => Ok(ak.clone()),
_ => Err(anyhow!("Statement argument {:?} is not a key.", self)),
_ => Err(Error::invalid_statement_arg(
self.clone(),
"key".to_string(),
)),
}
}
}