Skip to content

Commit 8a4cc05

Browse files
committed
core: Classify StoreError as non/deterministic
1 parent efda72e commit 8a4cc05

File tree

2 files changed

+63
-5
lines changed

2 files changed

+63
-5
lines changed

core/src/subgraph/error.rs

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
use graph::data::subgraph::schema::SubgraphError;
2-
use graph::prelude::{thiserror, Error, StoreError};
2+
use graph::env::ENV_VARS;
3+
use graph::prelude::{anyhow, thiserror, Error, StoreError};
34

45
pub trait DeterministicError: std::fmt::Debug + std::fmt::Display + Send + Sync + 'static {}
56

67
impl DeterministicError for SubgraphError {}
78

9+
impl DeterministicError for StoreError {}
10+
11+
impl DeterministicError for anyhow::Error {}
12+
813
/// An error happened during processing and we need to classify errors into
914
/// deterministic and non-deterministic errors. This struct holds the result
1015
/// of that classification
@@ -26,7 +31,34 @@ impl ProcessingError {
2631
pub fn is_deterministic(&self) -> bool {
2732
matches!(self, ProcessingError::Deterministic(_))
2833
}
34+
35+
pub fn detail(self, ctx: &str) -> ProcessingError {
36+
match self {
37+
ProcessingError::Unknown(e) => {
38+
let x = e.context(ctx.to_string());
39+
ProcessingError::Unknown(x)
40+
}
41+
ProcessingError::Deterministic(e) => {
42+
ProcessingError::Deterministic(Box::new(anyhow!("{e}").context(ctx.to_string())))
43+
}
44+
ProcessingError::Canceled => ProcessingError::Canceled,
45+
}
46+
}
2947
}
48+
49+
/// Similar to `anyhow::Context`, but for `Result<T, ProcessingError>`. We
50+
/// call the method `detail` to avoid ambiguity with anyhow's `context`
51+
/// method
52+
pub trait DetailHelper<T, E> {
53+
fn detail(self: Self, ctx: &str) -> Result<T, ProcessingError>;
54+
}
55+
56+
impl<T> DetailHelper<T, ProcessingError> for Result<T, ProcessingError> {
57+
fn detail(self, ctx: &str) -> Result<T, ProcessingError> {
58+
self.map_err(|e| e.detail(ctx))
59+
}
60+
}
61+
3062
/// Implement this for errors that are always non-deterministic.
3163
pub(crate) trait NonDeterministicErrorHelper<T, E> {
3264
fn non_deterministic(self: Self) -> Result<T, ProcessingError>;
@@ -43,3 +75,26 @@ impl<T> NonDeterministicErrorHelper<T, StoreError> for Result<T, StoreError> {
4375
self.map_err(|e| ProcessingError::Unknown(Error::from(e)))
4476
}
4577
}
78+
79+
/// Implement this for errors where it depends on the details whether they
80+
/// are deterministic or not.
81+
pub(crate) trait ClassifyErrorHelper<T, E> {
82+
fn classify(self: Self) -> Result<T, ProcessingError>;
83+
}
84+
85+
impl<T> ClassifyErrorHelper<T, StoreError> for Result<T, StoreError> {
86+
fn classify(self) -> Result<T, ProcessingError> {
87+
self.map_err(|e| {
88+
if ENV_VARS.mappings.store_errors_are_nondeterministic {
89+
// Old behavior, just in case the new behavior causes issues
90+
ProcessingError::Unknown(Error::from(e))
91+
} else {
92+
if e.is_deterministic() {
93+
ProcessingError::Deterministic(Box::new(e))
94+
} else {
95+
ProcessingError::Unknown(Error::from(e))
96+
}
97+
}
98+
})
99+
}
100+
}

core/src/subgraph/runner.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use crate::subgraph::context::IndexingContext;
2-
use crate::subgraph::error::{NonDeterministicErrorHelper as _, ProcessingError};
2+
use crate::subgraph::error::{
3+
ClassifyErrorHelper as _, DetailHelper as _, NonDeterministicErrorHelper as _, ProcessingError,
4+
};
35
use crate::subgraph::inputs::IndexingInputs;
46
use crate::subgraph::state::IndexingState;
57
use crate::subgraph::stream::new_block_stream;
@@ -746,7 +748,8 @@ where
746748
is_caught_up,
747749
)
748750
.await
749-
.non_deterministic()?;
751+
.classify()
752+
.detail("Failed to transact block operations")?;
750753

751754
// For subgraphs with `nonFatalErrors` feature disabled, we consider
752755
// any error as fatal.
@@ -1476,8 +1479,8 @@ where
14761479
is_caught_up,
14771480
)
14781481
.await
1479-
.context("Failed to transact block operations")
1480-
.non_deterministic()?;
1482+
.classify()
1483+
.detail("Failed to transact block operations")?;
14811484

14821485
// For subgraphs with `nonFatalErrors` feature disabled, we consider
14831486
// any error as fatal.

0 commit comments

Comments
 (0)