add error handling

This commit is contained in:
vms 2020-09-30 13:11:27 +03:00
parent 263385bc5b
commit 94e8351294
6 changed files with 102 additions and 26 deletions

View File

@ -33,8 +33,8 @@ pub fn invoke(init_user_id: String, aqua: String, data: String) -> StepperOutcom
#[fce]
pub struct CallServiceResult {
pub result: i32,
pub outcome: String,
pub ret_code: i32,
pub result: String,
}
#[fce]

71
src/stepper/errors.rs Normal file
View File

@ -0,0 +1,71 @@
/*
* 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.
*/
use super::StepperOutcome;
use serde_sexpr::Error as SExprError;
use std::convert::Into;
use std::error::Error;
#[derive(Debug)]
pub enum AquamarineError {
/// FaaS errors.
ParseError(SExprError),
/// Aquamarine result deserialization errors.
ExecutionError(String),
}
impl Error for AquamarineError {}
impl std::fmt::Display for AquamarineError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
match self {
AquamarineError::ParseError(err) => write!(f, "{}", err),
AquamarineError::ExecutionError(err_msg) => write!(f, "{}", err_msg),
}
}
}
impl From<SExprError> for AquamarineError {
fn from(err: SExprError) -> Self {
AquamarineError::ParseError(err)
}
}
impl From<std::convert::Infallible> for AquamarineError {
fn from(_: std::convert::Infallible) -> Self {
unreachable!()
}
}
impl Into<StepperOutcome> for AquamarineError {
fn into(self) -> StepperOutcome {
match self {
AquamarineError::ParseError(err) => StepperOutcome {
ret_code: 1,
data: format!("{}", err),
next_peer_pks: vec![],
},
AquamarineError::ExecutionError(err) => StepperOutcome {
ret_code: 2,
data: err,
next_peer_pks: vec![],
},
}
}
}

View File

@ -14,8 +14,9 @@
* limitations under the License.
*/
use super::Result;
use super::StepperOutcome;
use crate::instructions::Instruction;
use super::stepper_outcome::StepperOutcome;
pub(crate) fn execute_aqua(init_user_id: String, aqua: String, data: String) -> StepperOutcome {
log::info!(
@ -25,23 +26,18 @@ pub(crate) fn execute_aqua(init_user_id: String, aqua: String, data: String) ->
data
);
let outcome = StepperOutcome {
execute_aqua_impl(init_user_id, aqua, data).unwrap_or_else(Into::into)
}
fn execute_aqua_impl(init_user_id: String, aqua: String, data: String) -> Result<StepperOutcome> {
let parsed_aqua = serde_sexpr::from_str::<Vec<Instruction>>(&aqua)?;
log::info!("parsed_aqua: {:?}", parsed_aqua);
super::stepper::execute(parsed_aqua);
Ok(StepperOutcome {
ret_code: 0,
data,
next_peer_pks: vec![init_user_id],
};
let parsed_aqua = match serde_sexpr::from_str::<Vec<Instruction>>(&aqua) {
Ok(parsed) => parsed,
Err(e) => {
log::error!("supplied aqua script can't be parsed: {:?}", e);
return outcome;
}
};
log::info!("parsed_aqua: {:?}", parsed_aqua);
super::stepper::execute(parsed_aqua);
outcome
})
}

View File

@ -14,10 +14,15 @@
* limitations under the License.
*/
mod errors;
mod execution;
mod stepper;
mod stepper_outcome;
pub(crate) use execution::execute_aqua;
pub use stepper_outcome::StepperOutcome;
pub(crate) use errors::AquamarineError;
pub(crate) use execution::execute_aqua;
pub(crate) use stepper::ExecutableInstruction;
pub(self) type Result<T> = std::result::Result<T, AquamarineError>;

View File

@ -20,8 +20,12 @@ use serde::{Deserialize, Serialize};
#[fce]
#[derive(Serialize, Deserialize)]
pub struct StepperOutcome {
// 0 means success
/// A return code, where 0 means success.
pub ret_code: i32,
/// Contains data if ret_code == 0, otherwise error message (that could be empty string).
pub data: String,
/// Public keys of peers that should receive data.
pub next_peer_pks: Vec<String>,
}

View File

@ -4,19 +4,19 @@ fn main() {}
#[fce]
pub struct CallServiceResult {
pub result: i32,
pub outcome: Vec<u8>,
pub ret_code: i32,
pub result: String,
}
#[fce]
pub fn call_service(service_id: String, fn_name: String, args: Vec<u8>) -> CallServiceResult {
pub fn call_service(service_id: String, fn_name: String, args: String) -> CallServiceResult {
println!(
"call service invoked with:\n service_id: {}\n fn_name: {}\n args: {:?}",
service_id, fn_name, args
);
CallServiceResult {
result: 0,
outcome: vec![1, 2, 3],
ret_code: 0,
result: args,
}
}