Handle sp_runtime::ModuleError substrate updates (#492)

* codegen: Handle new errors of type [u8; 4] with backwards compatibility

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* codegen: Add comments about the compatibility of `DispatchError::Module`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* codegen: Handle legacy cases appropriately

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* codegen: Introduce `ModuleErrorType` for compatibility versioning

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* codegen: Implement `module_error_type` helper

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* codegen: Implement `quote::ToTokens` for `ModuleErrorType`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* codegen: Rename new error to ArrayError

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* codegen: Add strict checks for ModuleError

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* codegen: Fix cargo fmt

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* codegen, subxt: Expose the error's raw bytes to user

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt: Update polkadot with ModuleErrorRaw

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt: Rename `ModuleErrorRaw` to `ModuleErrorData`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* subxt: Expose method to obtain error index

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>

* codegen: Rename `ModuleErrorRaw` to `ModuleErrorData`

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
This commit is contained in:
Alexandru Vasile
2022-03-31 12:26:36 +03:00
committed by GitHub
parent 3d669f97c6
commit 9318f62850
5 changed files with 570 additions and 262 deletions
+23 -1
View File
@@ -182,6 +182,28 @@ pub struct ModuleError {
pub error: String,
/// A description of the error.
pub description: Vec<String>,
/// A byte representation of the error.
pub error_data: ModuleErrorData,
}
/// The error details about a module error that has occurred.
///
/// **Note**: Structure used to obtain the underlying bytes of a ModuleError.
#[derive(Clone, Debug, thiserror::Error)]
#[error("Pallet index {pallet_index}: raw error: {error:?}")]
pub struct ModuleErrorData {
/// Index of the pallet that the error came from.
pub pallet_index: u8,
/// Raw error bytes.
pub error: [u8; 4],
}
impl ModuleErrorData {
/// Obtain the error index from the underlying byte data.
pub fn error_index(&self) -> u8 {
// Error index is utilized as the first byte from the error array.
self.error[0]
}
}
/// This trait is automatically implemented for the generated `DispatchError`,
@@ -190,5 +212,5 @@ pub struct ModuleError {
pub trait HasModuleError {
/// If the error has a `Module` variant, return a tuple of the
/// pallet index and error index. Else, return `None`.
fn module_error_indices(&self) -> Option<(u8, u8)>;
fn module_error_data(&self) -> Option<ModuleErrorData>;
}
+1
View File
@@ -81,6 +81,7 @@ pub use crate::{
Error,
GenericError,
HasModuleError,
ModuleErrorData,
RuntimeError,
TransactionError,
},
+7 -4
View File
@@ -389,14 +389,17 @@ impl<'client, T: Config, E: Decode + HasModuleError, Evs: Decode>
let ev = ev?;
if &ev.pallet == "System" && &ev.variant == "ExtrinsicFailed" {
let dispatch_error = E::decode(&mut &*ev.data)?;
if let Some((pallet_idx, error_idx)) =
dispatch_error.module_error_indices()
{
let details = self.client.metadata().error(pallet_idx, error_idx)?;
if let Some(error_data) = dispatch_error.module_error_data() {
// Error index is utilized as the first byte from the error array.
let details = self
.client
.metadata()
.error(error_data.pallet_index, error_data.error_index())?;
return Err(Error::Module(ModuleError {
pallet: details.pallet().to_string(),
error: details.error().to_string(),
description: details.description().to_vec(),
error_data,
}))
} else {
return Err(Error::Runtime(RuntimeError(dispatch_error)))