Task description
https://github.com/Concordium/concordium-smart-contract-tools/blob/main/front-end-tools/src/utils.ts#L199
Error decoding of nested errors is currently not captured correctly in the above line. An error can be nested e.g.:
{"Custom": [ {"CustomError1": []}]}
The scTool only displays the top-most error enum variant Custom in the cis2-library example.
Explanation of how nested errors are constructed in the smart contract
/// 2. Example: Deriving `Reject` in the smart contract with nested errors.
/// Nested errors are often used to inherit the errors from a smart
/// contract library such as the cis2-library.
/// ``
///
/// Library:
/// ```ignore
/// /// The custom errors the library can produce.
/// #[derive(Serialize, Debug, Reject, SchemaType)]
/// pub enum Cis2Error {
/// /// CustomErrorLibrary1 defined in smart contract logic.
/// CustomErrorLibrary1, // return_value: 00; error_code: -1
/// /// Nested error variant.
/// Custom(R),
/// // return_value: 0100; error_code: -1
/// // return_value: 0101; error_code: -2
/// // return_value: 0102; error_code: -3
/// // ...
/// /// CustomErrorLibrary2 defined in smart contract logic.
/// CustomErrorLibrary2, // return_value: 02; error_code: -3
/// }
/// ```
///
/// Smart contract:
/// ```ignore
/// /// The different errors the contract can produce.
/// #[derive(Serialize, Debug, PartialEq, Eq, Reject, SchemaType)]
/// pub enum CustomContractError {
/// /// CustomError1 defined in smart contract logic.
/// CustomError1, // return_value: 0100; error_code: -1
/// /// CustomError2 defined in smart contract logic.
/// CustomError2, // return_value: 0101; error_code: -2
/// /// CustomError3 defined in smart contract logic.
/// CustomError3, // return_value: 0102; error_code: -2
/// }
///
/// /// Mapping CustomContractError to ContractError
/// impl From for ContractError {
/// fn from(c: CustomContractError) -> Self { Cis2Error::Custom(c) }
/// }
///
/// pub type ContractError = Cis2Error;
///
/// pub type ContractResult = Result;
/// ```
///
/// The `Reject` macro assigns the `error_codes` starting from `-1` to the enum
/// variants and assigns the `return_values` by serializing the enum variants
/// starting with the topmost enum. The `return_values` are equivalent to the
/// enum tags of all enums in the nested chain.
///
/// The JSON value returned by this function for the above `CustomError1` is:
/// ```json
/// {\"Custom\/": Array [Object {\"CustomError1\/": Array []}]}
/// ```
A recursive approach is needed similar to below code for scTool as well to display nested errors meaningfully.
/// Write a custom display implementation for the error schema type.
/// This displays nested errors meaningfully.
impl std::fmt::Display for ErrorSchema {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.0 {
Value::Object(map) => {
if let Some(key) = map.keys().next() {
write!(f, "{}", key)?;
if let Some(value) = map.values().next() {
if value.is_array() {
write!(f, "{}", ErrorSchema(value.clone()))?;
}
}
}
}
Value::Array(arr) => {
if let Some(value) = arr.iter().next() {
write!(f, "::{}", ErrorSchema(value.clone()))?;
}
}
_ => write!(f, "{}", self.0)?,
}
Ok(())
}
}
Another limitation that once resolved needs to be applied to the scTool front-end is given in the comment of the PR:
Concordium/concordium-dapp-examples#88
Task description
https://github.com/Concordium/concordium-smart-contract-tools/blob/main/front-end-tools/src/utils.ts#L199
Error decoding of nested errors is currently not captured correctly in the above line. An error can be nested e.g.:
{"Custom": [ {"CustomError1": []}]}The
scToolonly displays the top-most error enum variantCustomin the cis2-library example.Explanation of how nested errors are constructed in the smart contract
A recursive approach is needed similar to below code for
scToolas well to display nested errors meaningfully.Another limitation that once resolved needs to be applied to the
scToolfront-end is given in the comment of the PR:Concordium/concordium-dapp-examples#88