expose module errors into metadata (#3752)

* expose module errors into metadata

* it checks

* Tests for error metadata

* Apply suggestions from code review

Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com>

* remove inherent errors from metadata

* bump version

* Apply suggestions from code review

Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com>

* Update srml/support/src/error.rs

Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
Xiliang Chen
2019-10-08 22:30:16 +13:00
committed by Bastian Köcher
parent 38a61861b1
commit 2c77262c8f
5 changed files with 94 additions and 12 deletions
+28 -6
View File
@@ -179,7 +179,7 @@ pub struct OuterEventMetadata {
>,
}
/// All the metadata about a event.
/// All the metadata about an event.
#[derive(Clone, PartialEq, Eq, Encode)]
#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))]
pub struct EventMetadata {
@@ -209,6 +209,25 @@ pub struct ModuleConstantMetadata {
pub documentation: DecodeDifferentArray<&'static str, StringBuf>,
}
/// All the metadata about a module error.
#[derive(Clone, PartialEq, Eq, Encode)]
#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))]
pub struct ErrorMetadata {
pub name: DecodeDifferentStr,
pub documentation: DecodeDifferentArray<&'static str, StringBuf>,
}
/// All the metadata about errors in a module.
pub trait ModuleErrorMetadata {
fn metadata() -> &'static [ErrorMetadata];
}
impl ModuleErrorMetadata for &'static str {
fn metadata() -> &'static [ErrorMetadata] {
&[]
}
}
/// A technical trait to store lazy initiated vec value as static dyn pointer.
pub trait DefaultByte: Send + Sync {
fn default_byte(&self) -> Vec<u8>;
@@ -326,8 +345,10 @@ pub enum RuntimeMetadata {
V5(RuntimeMetadataDeprecated),
/// Version 6 for runtime metadata. No longer used.
V6(RuntimeMetadataDeprecated),
/// Version 7 for runtime metadata.
V7(RuntimeMetadataV7),
/// Version 7 for runtime metadata. No longer used.
V7(RuntimeMetadataDeprecated),
/// Version 8 for runtime metadata.
V8(RuntimeMetadataV8),
}
/// Enum that should fail.
@@ -351,12 +372,12 @@ impl Decode for RuntimeMetadataDeprecated {
/// The metadata of a runtime.
#[derive(Eq, Encode, PartialEq)]
#[cfg_attr(feature = "std", derive(Decode, Debug, Serialize))]
pub struct RuntimeMetadataV7 {
pub struct RuntimeMetadataV8 {
pub modules: DecodeDifferentArray<ModuleMetadata>,
}
/// The latest version of the metadata.
pub type RuntimeMetadataLastVersion = RuntimeMetadataV7;
pub type RuntimeMetadataLastVersion = RuntimeMetadataV8;
/// All metadata about an runtime module.
#[derive(Clone, PartialEq, Eq, Encode)]
@@ -367,6 +388,7 @@ pub struct ModuleMetadata {
pub calls: ODFnA<FunctionMetadata>,
pub event: ODFnA<EventMetadata>,
pub constants: DFnA<ModuleConstantMetadata>,
pub errors: DFnA<ErrorMetadata>,
}
type ODFnA<T> = Option<DFnA<T>>;
@@ -380,6 +402,6 @@ impl Into<primitives::OpaqueMetadata> for RuntimeMetadataPrefixed {
impl Into<RuntimeMetadataPrefixed> for RuntimeMetadataLastVersion {
fn into(self) -> RuntimeMetadataPrefixed {
RuntimeMetadataPrefixed(META_RESERVED, RuntimeMetadata::V7(self))
RuntimeMetadataPrefixed(META_RESERVED, RuntimeMetadata::V8(self))
}
}
+9 -1
View File
@@ -23,7 +23,7 @@ pub use std::fmt;
pub use crate::codec::{Codec, EncodeLike, Decode, Encode, Input, Output, HasCompact, EncodeAsRef};
pub use srml_metadata::{
FunctionMetadata, DecodeDifferent, DecodeDifferentArray, FunctionArgumentMetadata,
ModuleConstantMetadata, DefaultByte, DefaultByteGetter,
ModuleConstantMetadata, DefaultByte, DefaultByteGetter, ModuleErrorMetadata, ErrorMetadata
};
pub use sr_primitives::{
weights::{
@@ -1298,6 +1298,14 @@ macro_rules! decl_module {
{ $( $other_where_bounds )* }
$( $constants )*
}
impl<$trait_instance: $trait_name $(<I>, $instance: $instantiable)?> $crate::dispatch::ModuleErrorMetadata
for $mod_type<$trait_instance $(, $instance)?> where $( $other_where_bounds )*
{
fn metadata() -> &'static [$crate::dispatch::ErrorMetadata] {
<$error_type as $crate::dispatch::ModuleErrorMetadata>::metadata()
}
}
}
}
+18 -2
View File
@@ -18,6 +18,7 @@
#[doc(hidden)]
pub use sr_primitives::traits::LookupError;
pub use srml_metadata::{ModuleErrorMetadata, ErrorMetadata, DecodeDifferent};
/// Declare an error type for a runtime module.
///
@@ -49,7 +50,7 @@ macro_rules! decl_error {
$(#[$attr:meta])*
pub enum $error:ident {
$(
$( #[$variant_attr:meta] )*
$( #[doc = $doc_attr:tt] )*
$name:ident
),*
$(,)?
@@ -62,7 +63,7 @@ macro_rules! decl_error {
Other(&'static str),
CannotLookup,
$(
$(#[$variant_attr])*
$( #[doc = $doc_attr] )*
$name
),*
}
@@ -115,6 +116,21 @@ macro_rules! decl_error {
$crate::dispatch::DispatchError::new(None, self.as_u8(), Some(self.as_str()))
}
}
impl $crate::error::ModuleErrorMetadata for $error {
fn metadata() -> &'static [$crate::error::ErrorMetadata] {
&[
$(
$crate::error::ErrorMetadata {
name: $crate::error::DecodeDifferent::Encode(stringify!($name)),
documentation: $crate::error::DecodeDifferent::Encode(&[
$( $doc_attr ),*
]),
}
),*
]
}
}
};
(@GENERATE_AS_U8
$self:ident
+36 -3
View File
@@ -17,7 +17,7 @@
pub use srml_metadata::{
DecodeDifferent, FnEncode, RuntimeMetadata, ModuleMetadata, RuntimeMetadataLastVersion,
DefaultByteGetter, RuntimeMetadataPrefixed, StorageEntryMetadata, StorageMetadata,
StorageEntryType, StorageEntryModifier, DefaultByte, StorageHasher
StorageEntryType, StorageEntryModifier, DefaultByte, StorageHasher, ModuleErrorMetadata
};
/// Implements the metadata support for the given runtime and all its modules.
@@ -96,6 +96,11 @@ macro_rules! __runtime_modules_to_metadata {
$crate::metadata::FnEncode(
$mod::$module::<$runtime $(, $mod::$instance )?>::module_constants_metadata
)
),
errors: $crate::metadata::DecodeDifferent::Encode(
$crate::metadata::FnEncode(
<$mod::$module::<$runtime $(, $mod::$instance )?> as $crate::metadata::ModuleErrorMetadata>::metadata
)
)
};
$( $rest )*
@@ -227,6 +232,7 @@ mod tests {
use srml_metadata::{
EventMetadata, StorageEntryModifier, StorageEntryType, FunctionMetadata, StorageEntryMetadata,
ModuleMetadata, RuntimeMetadataPrefixed, DefaultByte, ModuleConstantMetadata, DefaultByteGetter,
ErrorMetadata,
};
use codec::{Encode, Decode};
use crate::traits::Get;
@@ -278,7 +284,7 @@ mod tests {
}
mod event_module {
use crate::dispatch::Result;
use crate::dispatch::DispatchResult;
pub trait Trait {
type Origin;
@@ -296,7 +302,19 @@ mod tests {
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
fn aux_0(_origin) -> Result { unreachable!() }
type Error = Error;
fn aux_0(_origin) -> DispatchResult<Error> { unreachable!() }
}
}
crate::decl_error! {
pub enum Error {
/// Some user input error
UserInputError,
/// Something bad happened
/// this could be due to many reasons
BadThingHappened,
}
}
}
@@ -447,6 +465,7 @@ mod tests {
}
])
),
errors: DecodeDifferent::Encode(FnEncode(|| &[])),
},
ModuleMetadata {
name: DecodeDifferent::Encode("Module"),
@@ -469,6 +488,19 @@ mod tests {
])
)),
constants: DecodeDifferent::Encode(FnEncode(|| &[])),
errors: DecodeDifferent::Encode(FnEncode(|| &[
ErrorMetadata {
name: DecodeDifferent::Encode("UserInputError"),
documentation: DecodeDifferent::Encode(&[" Some user input error"]),
},
ErrorMetadata {
name: DecodeDifferent::Encode("BadThingHappened"),
documentation: DecodeDifferent::Encode(&[
" Something bad happened",
" this could be due to many reasons",
]),
},
])),
},
ModuleMetadata {
name: DecodeDifferent::Encode("Module2"),
@@ -505,6 +537,7 @@ mod tests {
])
)),
constants: DecodeDifferent::Encode(FnEncode(|| &[])),
errors: DecodeDifferent::Encode(FnEncode(|| &[])),
},
])
};
@@ -29,7 +29,10 @@ support::decl_event!(
support::decl_error! {
pub enum Error {
/// Test error documentation
TestError,
/// Error documentation
/// with multiple lines
AnotherError
}
}