2021-01-15 00:38:58 +03:00
|
|
|
/*
|
|
|
|
* Copyright 2020 Fluence Labs Limited
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2021-12-28 16:59:55 +03:00
|
|
|
use super::Joinable;
|
|
|
|
use super::LastErrorAffectable;
|
2021-12-29 19:51:18 +03:00
|
|
|
use crate::execution_step::execution_context::LastErrorObjectError;
|
2021-10-18 23:23:30 +03:00
|
|
|
use crate::execution_step::lambda_applier::LambdaError;
|
2021-01-15 00:38:58 +03:00
|
|
|
use crate::JValue;
|
2021-12-17 22:02:16 +03:00
|
|
|
use crate::ToErrorCode;
|
2021-01-15 00:38:58 +03:00
|
|
|
|
2021-09-02 18:01:21 +03:00
|
|
|
use strum::IntoEnumIterator;
|
|
|
|
use strum_macros::EnumDiscriminants;
|
|
|
|
use strum_macros::EnumIter;
|
2021-01-15 00:38:58 +03:00
|
|
|
use thiserror::Error as ThisError;
|
|
|
|
|
2021-02-11 15:39:37 +03:00
|
|
|
use std::rc::Rc;
|
|
|
|
|
2021-12-21 11:37:35 +03:00
|
|
|
/// Catchable errors arisen during AIR script execution. Catchable here means that these errors
|
|
|
|
/// could be handled by a xor instruction and their error_code could be used in a match
|
|
|
|
/// instruction.
|
2021-09-02 18:01:21 +03:00
|
|
|
#[derive(ThisError, EnumDiscriminants, Debug)]
|
|
|
|
#[strum_discriminants(derive(EnumIter))]
|
2021-12-21 11:37:35 +03:00
|
|
|
pub enum CatchableError {
|
2021-01-15 00:38:58 +03:00
|
|
|
/// An error is occurred while calling local service via call_service.
|
2021-06-10 10:48:19 +03:00
|
|
|
#[error("Local service error, ret_code is {0}, error message is '{1}'")]
|
2021-02-11 15:39:37 +03:00
|
|
|
LocalServiceError(i32, Rc<String>),
|
2021-01-15 00:38:58 +03:00
|
|
|
|
2021-11-24 17:57:14 +03:00
|
|
|
/// Variable with such a name wasn't defined during AIR script execution.
|
2021-12-21 11:37:35 +03:00
|
|
|
/// This error type is used in order to support the join behaviour and
|
|
|
|
/// it's ok if some variable hasn't been defined yet, due to the par nature of AIR.
|
2021-11-24 17:57:14 +03:00
|
|
|
#[error("variable with name '{0}' wasn't defined during script execution")]
|
2021-01-15 00:38:58 +03:00
|
|
|
VariableNotFound(String),
|
|
|
|
|
2021-10-20 23:35:46 +03:00
|
|
|
/// Provided JValue has incompatible type with a requested one.
|
2021-12-15 17:39:26 +03:00
|
|
|
#[error(
|
|
|
|
"expected JValue type '{expected_value_type}' for the variable `{variable_name}`, but got '{actual_value}'"
|
|
|
|
)]
|
|
|
|
IncompatibleJValueType {
|
|
|
|
variable_name: String,
|
|
|
|
actual_value: JValue,
|
|
|
|
expected_value_type: &'static str,
|
|
|
|
},
|
2021-01-15 00:38:58 +03:00
|
|
|
|
2021-10-18 23:23:30 +03:00
|
|
|
/// A fold instruction must iterate over array value.
|
2023-03-09 14:37:39 +03:00
|
|
|
#[error("expression '{1}' returned non-array value '{0}' for a fold iterable")]
|
2021-10-18 23:23:30 +03:00
|
|
|
FoldIteratesOverNonArray(JValue, String),
|
|
|
|
|
2021-01-27 00:37:58 +03:00
|
|
|
/// This error type is produced by a match to notify xor that compared values aren't equal.
|
|
|
|
#[error("match is used without corresponding xor")]
|
2021-12-28 16:59:55 +03:00
|
|
|
MatchValuesNotEqual,
|
2021-02-11 15:39:37 +03:00
|
|
|
|
|
|
|
/// This error type is produced by a mismatch to notify xor that compared values aren't equal.
|
|
|
|
#[error("mismatch is used without corresponding xor")]
|
2021-12-28 16:59:55 +03:00
|
|
|
MismatchValuesEqual,
|
2021-02-18 17:30:14 +03:00
|
|
|
|
2021-12-16 21:34:27 +03:00
|
|
|
/// This error type is produced by a fail instruction.
|
2021-12-28 16:59:55 +03:00
|
|
|
#[error("fail with '{error}' is used without corresponding xor")]
|
|
|
|
UserError { error: Rc<JValue> },
|
2021-12-16 21:34:27 +03:00
|
|
|
|
2021-12-21 11:37:35 +03:00
|
|
|
/// An error occurred while trying to apply lambda to a value.
|
2021-09-20 14:49:20 +03:00
|
|
|
#[error(transparent)]
|
2021-12-21 11:37:35 +03:00
|
|
|
LambdaApplierError(#[from] LambdaError),
|
2021-08-24 16:14:15 +03:00
|
|
|
|
2021-12-29 19:51:18 +03:00
|
|
|
/// This error type is produced by a fail instruction that tries to throw a scalar that have inappropriate type.
|
|
|
|
#[error(transparent)]
|
|
|
|
InvalidLastErrorObjectError(#[from] LastErrorObjectError),
|
2022-04-20 11:43:46 +03:00
|
|
|
|
|
|
|
/// A new with this variable name was met and right after that it was accessed
|
|
|
|
/// that is prohibited.
|
|
|
|
#[error("variable with name '{0}' was cleared by new and then wasn't set")]
|
|
|
|
VariableWasNotInitializedAfterNew(String),
|
2022-08-26 00:43:43 +03:00
|
|
|
|
2022-09-08 16:58:04 +03:00
|
|
|
/// This error type is occurred when the length functor applied to a value of non-array type.
|
|
|
|
#[error("the length functor could applied only to an array-like value, but it's applied to '{0}'")]
|
|
|
|
LengthFunctorAppliedToNotArray(JValue),
|
2023-03-07 20:26:25 +03:00
|
|
|
|
|
|
|
/// Call gets non-string JValue resolving triplet parts.
|
|
|
|
#[error("call cannot resolve non-String triplet variable part `{variable_name}` with value '{actual_value}'")]
|
|
|
|
NonStringValueInTripletResolution {
|
|
|
|
variable_name: String,
|
|
|
|
actual_value: JValue,
|
|
|
|
},
|
2021-08-24 16:14:15 +03:00
|
|
|
}
|
|
|
|
|
2021-12-21 11:37:35 +03:00
|
|
|
impl From<LambdaError> for Rc<CatchableError> {
|
2021-10-18 23:23:30 +03:00
|
|
|
fn from(e: LambdaError) -> Self {
|
2021-12-21 11:37:35 +03:00
|
|
|
Rc::new(CatchableError::LambdaApplierError(e))
|
2021-10-18 23:23:30 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-21 11:37:35 +03:00
|
|
|
impl ToErrorCode for Rc<CatchableError> {
|
2021-12-17 22:02:16 +03:00
|
|
|
fn to_error_code(&self) -> i64 {
|
2021-12-21 11:37:35 +03:00
|
|
|
self.as_ref().to_error_code()
|
2021-12-17 22:02:16 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-21 11:37:35 +03:00
|
|
|
impl ToErrorCode for CatchableError {
|
2021-12-17 22:02:16 +03:00
|
|
|
fn to_error_code(&self) -> i64 {
|
2021-12-21 11:37:35 +03:00
|
|
|
use crate::utils::CATCHABLE_ERRORS_START_ID;
|
|
|
|
crate::generate_to_error_code!(self, CatchableError, CATCHABLE_ERRORS_START_ID)
|
2021-01-15 00:38:58 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-28 16:59:55 +03:00
|
|
|
impl LastErrorAffectable for CatchableError {
|
|
|
|
fn affects_last_error(&self) -> bool {
|
|
|
|
!matches!(
|
|
|
|
self,
|
|
|
|
CatchableError::MatchValuesNotEqual | CatchableError::MismatchValuesEqual
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-10 13:00:11 +03:00
|
|
|
macro_rules! log_join {
|
|
|
|
($($args:tt)*) => {
|
2023-03-11 01:09:23 +07:00
|
|
|
log::trace!(target: air_log_targets::JOIN_BEHAVIOUR, $($args)*)
|
2021-06-10 13:00:11 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[rustfmt::skip::macros(log_join)]
|
2021-12-21 11:37:35 +03:00
|
|
|
impl Joinable for CatchableError {
|
2021-06-10 13:00:11 +03:00
|
|
|
/// Returns true, if supplied error is related to variable not found errors type.
|
|
|
|
/// Print log if this is joinable error type.
|
|
|
|
fn is_joinable(&self) -> bool {
|
2021-12-21 11:37:35 +03:00
|
|
|
use CatchableError::*;
|
2021-06-10 13:00:11 +03:00
|
|
|
|
|
|
|
match self {
|
|
|
|
VariableNotFound(var_name) => {
|
|
|
|
log_join!(" waiting for an argument with name '{}'", var_name);
|
|
|
|
true
|
|
|
|
}
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|