From b5cc77038f72391bd41f8a7fb56cde876ffe3ba2 Mon Sep 17 00:00:00 2001 From: Eric Harris-Braun Date: Wed, 8 Apr 2020 12:52:07 -0400 Subject: [PATCH] refactored correct processing of validation errors for all workflows --- .../core/src/nucleus/validation/app_entry.rs | 4 +- crates/core/src/nucleus/validation/mod.rs | 69 ++++++++++++++++--- crates/core/src/workflows/hold_entry.rs | 26 +++---- .../core/src/workflows/hold_entry_remove.rs | 25 +++---- .../core/src/workflows/hold_entry_update.rs | 30 +++----- crates/core/src/workflows/hold_link.rs | 33 ++++----- crates/core/src/workflows/remove_link.rs | 33 ++++----- 7 files changed, 123 insertions(+), 97 deletions(-) diff --git a/crates/core/src/nucleus/validation/app_entry.rs b/crates/core/src/nucleus/validation/app_entry.rs index 8013545e26..c58ea7573f 100644 --- a/crates/core/src/nucleus/validation/app_entry.rs +++ b/crates/core/src/nucleus/validation/app_entry.rs @@ -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); diff --git a/crates/core/src/nucleus/validation/mod.rs b/crates/core/src/nucleus/validation/mod.rs index e3e84a6a14..1bc543776e 100644 --- a/crates/core/src/nucleus/validation/mod.rs +++ b/crates/core/src/nucleus/validation/mod.rs @@ -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, + 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, @@ -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(|| { @@ -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 { diff --git a/crates/core/src/workflows/hold_entry.rs b/crates/core/src/workflows/hold_entry.rs index e619812dce..77edb30c17 100644 --- a/crates/core/src/workflows/hold_entry.rs +++ b/crates/core/src/workflows/hold_entry.rs @@ -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, @@ -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!( diff --git a/crates/core/src/workflows/hold_entry_remove.rs b/crates/core/src/workflows/hold_entry_remove.rs index de661db886..bc5287fbcb 100644 --- a/crates/core/src/workflows/hold_entry_remove.rs +++ b/crates/core/src/workflows/hold_entry_remove.rs @@ -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)] @@ -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 diff --git a/crates/core/src/workflows/hold_entry_update.rs b/crates/core/src/workflows/hold_entry_update.rs index be5a87910a..155e8d95b7 100644 --- a/crates/core/src/workflows/hold_entry_update.rs +++ b/crates/core/src/workflows/hold_entry_update.rs @@ -2,7 +2,7 @@ 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::{ @@ -10,6 +10,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)] @@ -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( diff --git a/crates/core/src/workflows/hold_link.rs b/crates/core/src/workflows/hold_link.rs index 4ecb430abd..7387c1c2ed 100644 --- a/crates/core/src/workflows/hold_link.rs +++ b/crates/core/src/workflows/hold_link.rs @@ -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::{ @@ -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)] @@ -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!"); diff --git a/crates/core/src/workflows/remove_link.rs b/crates/core/src/workflows/remove_link.rs index 5cd0e63678..6a6ab65ab4 100644 --- a/crates/core/src/workflows/remove_link.rs +++ b/crates/core/src/workflows/remove_link.rs @@ -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)] @@ -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!");