1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
/*
* AquaVM Workflow Engine
*
* Copyright (C) 2024 Fluence DAO
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation version 3 of the
* License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use super::Stream;
use crate::execution_step::Generation;
use crate::execution_step::STREAM_MAX_SIZE;
use crate::CanonStreamMapError;
use crate::StreamMapError;
use crate::StreamMapKeyError;
use crate::ToErrorCode;
use air_interpreter_cid::CidCalculationError;
use air_interpreter_cid::CidRef;
use air_interpreter_data::ValueRef;
use air_interpreter_interface::CallArgumentsRepr;
use air_interpreter_interface::TetrapletsRepr;
use air_interpreter_sede::Representation;
use air_trace_handler::GenerationCompactificationError;
use air_trace_handler::IntConversionError;
use air_trace_handler::TraceHandlerError;
use strum::IntoEnumIterator;
use strum_macros::EnumDiscriminants;
use strum_macros::EnumIter;
use thiserror::Error as ThisError;
use std::rc::Rc;
/// Uncatchable errors arisen during AIR script execution. Uncatchable here means that these errors
/// couldn't be handled by a xor instruction and their error_code couldn't be used in a match
/// instruction. They are similar to JVM runtime errors and some of them could be caught only
/// while execution of AIR script, others (FoldStateNotFound and MultipleVariablesFound) are
/// checked additionally on the validation step, and presence here for convenience.
#[derive(ThisError, EnumDiscriminants, Debug)]
#[strum_discriminants(derive(EnumIter))]
pub enum UncatchableError {
/// Errors bubbled from a trace handler.
#[error("on instruction '{instruction}' trace handler encountered an error: {trace_error}")]
TraceError {
trace_error: TraceHandlerError,
instruction: String,
},
/// These errors are related to internal bug in the interpreter when result trace is corrupted.
#[error(transparent)]
GenerationCompactificationError(#[from] GenerationCompactificationError),
/// Integer casts, e.g. usize(=u64) to u32, might trigger such errors.
#[error(transparent)]
IntConversionError(#[from] IntConversionError),
/// Fold state wasn't found for such iterator name.
#[error("fold state not found for this iterable '{0}'")]
FoldStateNotFound(String),
/// Errors encountered while shadowing non-scalar values.
#[error("variable with name '{0}' can't be shadowed, shadowing isn't supported for iterables")]
IterableShadowing(String),
/// Multiple fold states found for such iterator name.
#[error("multiple iterable values found for iterable name '{0}'")]
MultipleIterableValues(String),
/// Errors occurred when result from data doesn't match to a call instruction, f.e. a call
/// could be applied to a stream, but result doesn't contain generation in a source position.
#[error("call result value {0:?} doesn't match with corresponding instruction")]
CallResultNotCorrespondToInstr(ValueRef),
/// Variable shadowing is not allowed, usually it's thrown when a AIR tries to assign value
/// for a variable not in a fold block or in a global scope but not right after new.
#[error("trying to shadow variable '{0}', but shadowing is allowed only inside fold blocks")]
ShadowingIsNotAllowed(String),
/// This error occurred when new tries to pop up a variable at the end, but scalar state doesn't
/// contain an appropriate variable. It should be considered as an internal error and shouldn't
/// be caught by a xor instruction.
#[error("new end block tries to pop up a variable '{scalar_name}' that wasn't defined at depth {depth}")]
ScalarsStateCorrupted { scalar_name: String, depth: usize },
#[error("failed to calculate value's CID")]
CidError(#[from] CidCalculationError),
/// We consider now that every CID should present in the data;
/// and not having any CID is considered a non-catching error.
#[error("{0} for CID {1:?} not found")]
ValueForCidNotFound(&'static str, Rc<CidRef>),
/// Errors occurred while insertion of a value inside stream that doesn't have corresponding generation.
#[error(
"stream doesn't have generation with number {generation}, supplied to the interpreter data is corrupted,\n\
stream is {stream:?}"
)]
StreamDontHaveSuchGeneration { stream: Stream, generation: Generation },
#[error("failed to deserialize to CallServiceFailed: {0}")]
MalformedCallServiceFailed(serde_json::Error),
/// Stream size estimate goes over a hardcoded limit.
#[error("stream size goes over the allowed limit of {STREAM_MAX_SIZE}")]
StreamSizeLimitExceeded,
/// CanonStreamMapKey related errors.
#[error(transparent)]
StreamMapKeyError(#[from] StreamMapKeyError),
/// Stream map related errors.
#[error(transparent)]
StreamMapError(#[from] StreamMapError),
/// CanonStreamMap related errors.
#[error(transparent)]
CanonStreamMapError(#[from] CanonStreamMapError),
/// Argument hash or tetraplet mismatch in a call/canon merged from current_data with an evaluated value.
#[error("{param} doesn't match expected parameters: expected {expected_value}, got {stored_value} ")]
InstructionParametersMismatch {
param: &'static str,
expected_value: String,
stored_value: String,
},
#[error("failed to sign data: {0}")]
SigningError(#[from] fluence_keypair::error::SigningError),
#[error("failed to serialize tetraplets {0}")]
TetrapletSerializationFailed(<TetrapletsRepr as Representation>::SerializeError),
#[error("failed to serialize call arguments {0}")]
CallArgumentsSerializationFailed(<CallArgumentsRepr as Representation>::SerializeError),
}
impl ToErrorCode for UncatchableError {
fn to_error_code(&self) -> i64 {
use crate::utils::UNCATCHABLE_ERRORS_START_ID;
crate::generate_to_error_code!(self, UncatchableError, UNCATCHABLE_ERRORS_START_ID)
}
}