Skip to content
This repository has been archived by the owner on Feb 3, 2023. It is now read-only.

Commit

Permalink
Merge pull request #2176 from holochain/validation-retry-not-fail
Browse files Browse the repository at this point in the history
refactored correct processing of validation errors for all workflows
  • Loading branch information
zippy authored Apr 8, 2020
2 parents d5d1836 + b5cc770 commit 64b3a2e
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 97 deletions.
4 changes: 1 addition & 3 deletions crates/core/src/nucleus/validation/app_entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@ pub async fn validate_app_entry(

let params = EntryValidationArgs {
validation_data: entry_to_validation_data(context.clone(), &entry, link, validation_data)
.map_err(|_| {
ValidationError::Fail("Could not get entry validation".to_string())
})?,
.map_err(|e| ValidationError::Error(e))?,
};
let call = CallbackFnCall::new(&zome_name, "__hdk_validate_app_entry", params);

Expand Down
69 changes: 61 additions & 8 deletions crates/core/src/nucleus/validation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,55 @@ pub async fn validate_entry(
}
}

/// interprets the validation error from validate_entry. for use by the various workflows
pub fn process_validation_err(
src: &str,
context: Arc<Context>,
err: ValidationError,
addr: Address,
) -> HolochainError {
match err {
ValidationError::UnresolvedDependencies(dependencies) => {
log_debug!(context, "workflow/{}: {} could not be validated due to unresolved dependencies and will be tried later. List of missing dependencies: {:?}",
src,
addr,
dependencies,
);
HolochainError::ValidationPending
}
ValidationError::Fail(_) => {
log_warn!(
context,
"workflow/{}: Entry {} is NOT valid! Validation error: {:?}",
src,
addr,
err,
);
HolochainError::from(err)
}
ValidationError::Error(HolochainError::Timeout(e)) => {
log_warn!(
context,
"workflow/{}: Entry {} got timeout({}) during validation, retrying",
src,
addr,
e,
);
HolochainError::ValidationPending
}
_ => {
log_warn!(
context,
"workflow/{}: Entry {} Unexpected error during validation: {:?}",
src,
addr,
err,
);
HolochainError::from(err)
}
}
}

#[holochain_tracing_macros::newrelic_autotrace(HOLOCHAIN_CORE)]
pub fn entry_to_validation_data(
context: Arc<Context>,
Expand All @@ -147,10 +196,12 @@ pub fn entry_to_validation_data(
validation_data: validation_data.clone(),
})
})
.unwrap_or_else(|_| {
Err(HolochainError::ErrorGeneric(
"Could not find Entry".to_string(),
))
.unwrap_or_else(|e| match e {
HolochainError::Timeout(_) => Err(e),
_ => Err(HolochainError::ErrorGeneric(format!(
"Could not find App Entry during validation, got err: {}",
e
))),
})
})
.unwrap_or_else(|| {
Expand All @@ -169,10 +220,12 @@ pub fn entry_to_validation_data(
validation_data: validation_data.clone(),
})
})
.unwrap_or_else(|_| {
Err(HolochainError::ErrorGeneric(
"Could not find Entry".to_string(),
))
.unwrap_or_else(|e| match e {
HolochainError::Timeout(_) => Err(e),
_ => Err(HolochainError::ErrorGeneric(format!(
"Could not find Delete Entry during validation, got err: {}",
e
))),
})
}
Entry::CapTokenGrant(_) => Ok(EntryValidationData::Create {
Expand Down
26 changes: 10 additions & 16 deletions crates/core/src/workflows/hold_entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
network::entry_with_header::EntryWithHeader, nucleus::validation::validate_entry,
};

use crate::{nucleus::validation::ValidationError, workflows::validation_package};
use crate::{nucleus::validation::process_validation_err, workflows::validation_package};
use holochain_core_types::{
error::HolochainError,
network::entry_aspect::EntryAspect,
Expand Down Expand Up @@ -47,22 +47,16 @@ pub async fn hold_entry_workflow(
entry_with_header.entry.clone(),
None,
validation_data,
&context
).await
&context,
)
.await
.map_err(|err| {
if let ValidationError::UnresolvedDependencies(dependencies) = &err {
log_debug!(context, "workflow/hold_entry: {} could not be validated due to unresolved dependencies and will be tried later. List of missing dependencies: {:?}",
entry_with_header.entry.address(),
dependencies,
);
HolochainError::ValidationPending
} else {
log_warn!(context, "workflow/hold_entry: Entry {} is NOT valid! Validation error: {:?}",
entry_with_header.entry.address(),
err,
);
HolochainError::from(err)
}
process_validation_err(
"hold_entry",
context.clone(),
err,
entry_with_header.entry.address(),
)
})?;

log_debug!(
Expand Down
25 changes: 11 additions & 14 deletions crates/core/src/workflows/hold_entry_remove.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ use crate::{
network::entry_with_header::EntryWithHeader, nucleus::validation::validate_entry,
};

use crate::{nucleus::validation::ValidationError, workflows::validation_package};
use crate::{nucleus::validation::process_validation_err, workflows::validation_package};
use holochain_core_types::{
error::HolochainError,
network::entry_aspect::EntryAspect,
validation::{EntryLifecycle, ValidationData},
};
use holochain_persistence_api::cas::content::AddressableContent;
use std::sync::Arc;

#[holochain_tracing_macros::newrelic_autotrace(HOLOCHAIN_CORE)]
Expand Down Expand Up @@ -39,20 +40,16 @@ pub async fn hold_remove_workflow(
entry_with_header.entry.clone(),
None,
validation_data,
&context
).await
&context,
)
.await
.map_err(|err| {
if let ValidationError::UnresolvedDependencies(dependencies) = &err {
log_debug!(context, "workflow/hold_remove: Entry removal could not be validated due to unresolved dependencies and will be tried later. List of missing dependencies: {:?}", dependencies);
HolochainError::ValidationPending
} else {
log_warn!(context, "workflow/hold_remove: Entry removal {:?} is NOT valid! Validation error: {:?}",
entry_with_header.entry,
err,
);
HolochainError::from(err)
}

process_validation_err(
"hold_remove",
context.clone(),
err,
entry_with_header.entry.address(),
)
})?;

// 4. If valid store the entry aspect in the local DHT shard
Expand Down
30 changes: 11 additions & 19 deletions crates/core/src/workflows/hold_entry_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ use crate::{
context::Context,
dht::actions::hold_aspect::hold_aspect,
network::entry_with_header::EntryWithHeader,
nucleus::validation::{validate_entry, ValidationError},
nucleus::validation::{process_validation_err, validate_entry},
workflows::validation_package,
};
use holochain_core_types::{
error::HolochainError,
network::entry_aspect::EntryAspect,
validation::{EntryLifecycle, ValidationData},
};
use holochain_persistence_api::cas::content::AddressableContent;
use std::sync::Arc;

#[holochain_tracing_macros::newrelic_autotrace(HOLOCHAIN_CORE)]
Expand Down Expand Up @@ -43,25 +44,16 @@ pub async fn hold_update_workflow(
};

// 3. Validate the entry
validate_entry(
entry.clone(),
Some(link.clone()),
validation_data,
&context
).await
.map_err(|err| {
if let ValidationError::UnresolvedDependencies(dependencies) = &err {
log_debug!(context, "workflow/hold_update: Entry update could not be validated due to unresolved dependencies and will be tried later. List of missing dependencies: {:?}", dependencies);
HolochainError::ValidationPending
} else {
log_warn!(context, "workflow/hold_update: Entry update {:?} is NOT valid! Validation error: {:?}",
entry_with_header.entry,
validate_entry(entry.clone(), Some(link.clone()), validation_data, &context)
.await
.map_err(|err| {
process_validation_err(
"hold_update",
context.clone(),
err,
);
HolochainError::from(err)
}

})?;
entry_with_header.entry.address(),
)
})?;

// 4. If valid store the entry aspect in the local DHT shard
let aspect = EntryAspect::Update(
Expand Down
33 changes: 14 additions & 19 deletions crates/core/src/workflows/hold_link.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
use crate::{
context::Context, dht::actions::hold_aspect::hold_aspect,
network::entry_with_header::EntryWithHeader, nucleus::validation::validate_entry,
};

use crate::{
nucleus::validation::ValidationError,
context::Context,
dht::actions::hold_aspect::hold_aspect,
network::entry_with_header::EntryWithHeader,
nucleus::validation::{process_validation_err, validate_entry},
workflows::{hold_entry::hold_entry_workflow, validation_package},
};
use holochain_core_types::{
Expand All @@ -13,6 +11,7 @@ use holochain_core_types::{
network::entry_aspect::EntryAspect,
validation::{EntryLifecycle, ValidationData},
};
use holochain_persistence_api::cas::content::AddressableContent;
use std::sync::Arc;

#[holochain_tracing_macros::newrelic_autotrace(HOLOCHAIN_CORE)]
Expand Down Expand Up @@ -58,20 +57,16 @@ pub async fn hold_link_workflow(
entry_with_header.entry.clone(),
None,
validation_data,
&context
).await
&context,
)
.await
.map_err(|err| {
if let ValidationError::UnresolvedDependencies(dependencies) = &err {
log_debug!(context, "workflow/hold_link: Link could not be validated due to unresolved dependencies and will be tried later. List of missing dependencies: {:?}", dependencies);
HolochainError::ValidationPending
} else {
log_warn!(context, "workflow/hold_link: Link {:?} is NOT valid! Validation error: {:?}",
entry_with_header.entry,
err,
);
HolochainError::from(err)
}

process_validation_err(
"hold_link",
context.clone(),
err,
entry_with_header.entry.address(),
)
})?;
log_debug!(context, "workflow/hold_link: is valid!");

Expand Down
33 changes: 15 additions & 18 deletions crates/core/src/workflows/remove_link.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
use crate::{
context::Context, dht::actions::hold_aspect::hold_aspect,
network::entry_with_header::EntryWithHeader, nucleus::validation::validate_entry,
workflows::hold_entry::hold_entry_workflow,
context::Context,
dht::actions::hold_aspect::hold_aspect,
network::entry_with_header::EntryWithHeader,
nucleus::validation::{process_validation_err, validate_entry},
workflows::{hold_entry::hold_entry_workflow, validation_package},
};

use crate::{nucleus::validation::ValidationError, workflows::validation_package};
use holochain_core_types::{
entry::Entry,
error::HolochainError,
network::entry_aspect::EntryAspect,
validation::{EntryLifecycle, ValidationData},
};
use holochain_persistence_api::cas::content::AddressableContent;
use std::sync::Arc;

#[holochain_tracing_macros::newrelic_autotrace(HOLOCHAIN_CORE)]
Expand Down Expand Up @@ -57,20 +58,16 @@ pub async fn remove_link_workflow(
entry_with_header.entry.clone(),
None,
validation_data,
&context
).await
&context,
)
.await
.map_err(|err| {
if let ValidationError::UnresolvedDependencies(dependencies) = &err {
log_debug!(context, "workflow/remove_link: Link could not be validated due to unresolved dependencies and will be tried later. List of missing dependencies: {:?}", dependencies);
HolochainError::ValidationPending
} else {
log_warn!(context, "workflow/remove_link: Link {:?} is NOT valid! Validation error: {:?}",
entry_with_header.entry,
err,
);
HolochainError::from(err)
}

process_validation_err(
"remove_link",
context.clone(),
err,
entry_with_header.entry.address(),
)
})?;

log_debug!(context, "workflow/remove_link: is valid!");
Expand Down

0 comments on commit 64b3a2e

Please sign in to comment.