Skip to content

Commit

Permalink
refactor(wit,grpc)!: Remove unhandled errors from execution-error
Browse files Browse the repository at this point in the history
WIT type `execution-error` now only carries timeouts and activity traps.
Other errors, like parameter parsing errors or nondeterminism,
will cause the parent chain to be marked as
`FinishedExecutionError::UnhandledChildExecutionError`.
  • Loading branch information
tomasol committed Feb 8, 2025
1 parent 8b0f07c commit 97136fd
Show file tree
Hide file tree
Showing 29 changed files with 876 additions and 495 deletions.
2 changes: 1 addition & 1 deletion assets/webui-version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
docker.io/getobelisk/webui:2025-02-05@sha256:a810583ae56f336a49bca3a58af59d02d7eee29889ce4faa18e0ae01f9ff4e6f
docker.io/getobelisk/webui:2025-02-07@sha256:68a675a69326f190a45ef933cc9e8d288e83a2c474dc4d39f383a9a13d1b4a3e
113 changes: 91 additions & 22 deletions crates/concepts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,28 +39,72 @@ pub type FinishedExecutionResult = Result<SupportedFunctionReturnValue, Finished

#[derive(thiserror::Error, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum FinishedExecutionError {
// Activity only
#[error("permanent timeout")]
PermanentTimeout,
#[error("nondeterminism detected: `{0}`")]
NondeterminismDetected(StrVariant),
#[error("permanent failure: {reason}")]
// Workflow only
#[error("unhandled child execution error {child_execution_id}")]
UnhandledChildExecutionError {
child_execution_id: ExecutionId,
root_cause_id: ExecutionId,
},
#[error("permanent failure: {reason_full}")]
PermanentFailure {
reason: String,
// Exists just for extracting reason of an activity trap, to avoid "activity trap: " prefix.
reason_inner: String,
// Contains reason_inner embedded in the error message
reason_full: String,
kind: PermanentFailureKind,
detail: Option<String>,
}, // temporary failure that is not retried (anymore)
},
}

impl FinishedExecutionError {
#[must_use]
pub fn as_pending_state_finished_error(&self) -> PendingStateFinishedError {
match self {
Self::PermanentTimeout => PendingStateFinishedError::Timeout,
Self::PermanentFailure { .. } => PendingStateFinishedError::ExecutionFailure,
Self::NondeterminismDetected(_) => PendingStateFinishedError::NondeterminismDetected,
FinishedExecutionError::PermanentTimeout => PendingStateFinishedError::Timeout,
FinishedExecutionError::UnhandledChildExecutionError { .. } => {
PendingStateFinishedError::UnhandledChildExecutionError
}
FinishedExecutionError::PermanentFailure { .. } => {
PendingStateFinishedError::ExecutionFailure
}
}
}
}

#[derive(Debug, Clone, Copy, derive_more::Display, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum PermanentFailureKind {
/// Applicable to Workflow
NondeterminismDetected,
/// Applicable to Workflow, Activity
ParamsParsingError,
/// Applicable to Workflow, Activity
CannotInstantiate,
/// Applicable to Workflow, Activity
ResultParsingError,
/// Applicable to Workflow
ImportedFunctionCallError,
/// Applicable to Activity
ActivityTrap,
/// Applicable to Workflow
WorkflowTrap,
/// Applicable to Workflow
JoinSetNameConflict,
/// Applicable to webhook endpoint
WebhookEndpointError,
}

#[derive(Debug, Clone, Copy, derive_more::Display, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum TrapKind {
#[display("trap")]
Trap,
#[display("post_return_trap")]
PostReturnTrap,
}

#[derive(Clone, Eq, derive_more::Display)]
pub enum StrVariant {
Static(&'static str),
Expand Down Expand Up @@ -465,11 +509,11 @@ pub enum SupportedFunctionReturnValue {

#[derive(Debug, thiserror::Error)]
pub enum ResultParsingError {
#[error("multi-value results are not supported")]
#[error("result cannot be parsed, multi-value results are not supported")]
MultiValue,
#[error(transparent)]
#[error("result cannot be parsed, {0}")]
TypeConversionError(#[from] val_json::type_wrapper::TypeConversionError),
#[error(transparent)]
#[error("result cannot be parsed, {0}")]
ValueConversionError(#[from] val_json::wast_val::WastValConversionError),
}

Expand Down Expand Up @@ -698,17 +742,28 @@ pub mod serde_params {

#[derive(Debug, thiserror::Error)]
pub enum ParamsParsingError {
#[error("error converting type of {idx}-th parameter: `{err}`")]
#[error("parameters cannot be parsed, cannot convert type of {idx}-th parameter")]
ParameterTypeError {
idx: usize,
err: TypeConversionError,
},
#[error(transparent)]
#[error("parameters cannot be deserialized: {0}")]
ParamsDeserializationError(serde_json::Error),
#[error("parameter cardinality mismatch, expected: {expected}, specified: {specified}")]
ParameterCardinalityMismatch { expected: usize, specified: usize },
}

impl ParamsParsingError {
#[must_use]
pub fn detail(&self) -> Option<String> {
match self {
ParamsParsingError::ParameterTypeError { err, .. } => Some(format!("{err:?}")),
ParamsParsingError::ParamsDeserializationError(err) => Some(format!("{err:?}")),
ParamsParsingError::ParameterCardinalityMismatch { .. } => None,
}
}
}

#[derive(Debug, thiserror::Error)]
pub enum ParamsFromJsonError {
#[error("value must be a json array containing function parameters")]
Expand Down Expand Up @@ -1131,7 +1186,7 @@ impl JoinSetId {
Ok(Self {
execution_id,
kind,
name: check_name(name, ALLOWED_JSON_SET_CHARS)?,
name: check_name(name, CHARSET_EXTRA_JSON_SET)?,
})
}

Expand All @@ -1144,7 +1199,7 @@ impl JoinSetId {
}
}
const CHARSET_JOIN_SET_NAME: &str =
const_format::concatcp!(CHARSET_ALPHANUMERIC, ALLOWED_JSON_SET_CHARS);
const_format::concatcp!(CHARSET_ALPHANUMERIC, CHARSET_EXTRA_JSON_SET);

pub const CHARSET_ALPHANUMERIC: &str =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Expand Down Expand Up @@ -1202,7 +1257,7 @@ impl FromStr for JoinSetKind {
}

const JOIN_SET_ID_INFIX: char = ':';
const ALLOWED_JSON_SET_CHARS: &str = "_-/.";
const CHARSET_EXTRA_JSON_SET: &str = "_-/.";

impl FromStr for JoinSetId {
type Err = JoinSetIdParseError;
Expand Down Expand Up @@ -1239,11 +1294,25 @@ pub enum JoinSetIdParseError {

impl<'a> Arbitrary<'a> for JoinSetId {
fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
Ok(Self {
execution_id: ExecutionId::arbitrary(u)?,
kind: JoinSetKind::UserDefinedRandom,
name: StrVariant::from(String::arbitrary(u)?),
})
let name: String = {
let length_inclusive = u.int_in_range(0..=10).unwrap();
(0..=length_inclusive)
.map(|_| {
let idx = u.choose_index(CHARSET_JOIN_SET_NAME.len()).unwrap();
CHARSET_JOIN_SET_NAME
.chars()
.nth(idx)
.expect("idx is < charset.len()")
})
.collect()
};

Ok(JoinSetId::new(
ExecutionId::arbitrary(u)?,
JoinSetKind::UserDefinedRandom,
StrVariant::from(name),
)
.unwrap())
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ expression: ser
---
[
"timeout",
"nondeterminism_detected",
"unhandled_child_execution_error",
"execution_failure",
"fallible_error",
"ok"
Expand Down
9 changes: 6 additions & 3 deletions crates/concepts/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,8 @@ pub const DUMMY_TEMPORARILY_TIMED_OUT: ExecutionEventInner =
};
pub const DUMMY_TEMPORARILY_FAILED: ExecutionEventInner = ExecutionEventInner::TemporarilyFailed {
backoff_expires_at: DateTime::from_timestamp_nanos(0),
reason: StrVariant::empty(),
reason_full: StrVariant::empty(),
reason_inner: StrVariant::empty(),
detail: None,
};

Expand Down Expand Up @@ -310,7 +311,9 @@ pub enum ExecutionEventInner {
TemporarilyFailed {
backoff_expires_at: DateTime<Utc>,
#[arbitrary(value = StrVariant::Static("reason"))]
reason: StrVariant,
reason_full: StrVariant,
#[arbitrary(value = StrVariant::Static("reason inner"))]
reason_inner: StrVariant,
detail: Option<String>,
},
// Created by the executor holding last lock.
Expand Down Expand Up @@ -1027,7 +1030,7 @@ impl From<&FinishedExecutionResult> for PendingStateFinishedResultKind {
#[strum(serialize_all = "snake_case")]
pub enum PendingStateFinishedError {
Timeout,
NondeterminismDetected,
UnhandledChildExecutionError,
ExecutionFailure,
FallibleError,
}
Expand Down
Loading

0 comments on commit 97136fd

Please sign in to comment.