diff --git a/xtask/src/gen_doc.rs b/xtask/src/gen_doc.rs
index b28d00692141d5e7b1fd04745eee1aa55170a87b..eb5dc2d8145a80a6d17a626b04dc89b39632a8e3 100644
--- a/xtask/src/gen_doc.rs
+++ b/xtask/src/gen_doc.rs
@@ -440,67 +440,96 @@ fn get_max_weight_from_metadata_v15(
     }
 }
 
-fn format_type(ty: &Type<PortableForm>, types: &PortableRegistry) -> String {
+fn format_type(ty: &Type<PortableForm>, types: &PortableRegistry) -> Result<String> {
     let path = ty.path.to_string();
 
     match &ty.type_def {
         TypeDef::Composite(_) => {
-            let generics = format_generics(&ty.type_params, types);
-            format!("{}{}", path, generics)
+            let generics = format_generics(&ty.type_params, types)?;
+            Ok(format!("{}{}", path, generics))
         }
         TypeDef::Variant(_) => {
-            let generics = format_generics(&ty.type_params, types);
-            format!("{}{}", path, generics)
+            let generics = format_generics(&ty.type_params, types)?;
+            Ok(format!("{}{}", path, generics))
         }
         TypeDef::Sequence(seq) => {
-            let element_type = resolve_type(seq.type_param.id, types);
-            format!("Vec<{}>", element_type)
+            let element_type = resolve_type(seq.type_param.id, types)?;
+            Ok(format!("Vec<{}>", element_type))
         }
         TypeDef::Array(arr) => {
-            let element_type = resolve_type(arr.type_param.id, types);
-            format!("[{}; {}]", element_type, arr.len)
+            let element_type = resolve_type(arr.type_param.id, types)?;
+            Ok(format!("[{}; {}]", element_type, arr.len))
         }
         TypeDef::Tuple(tuple) => {
-            let elements: Vec<String> = tuple
+            let elements = tuple
                 .fields
                 .iter()
                 .map(|f| resolve_type(f.id, types))
-                .collect();
-            format!("({})", elements.join(", "))
-        }
-        TypeDef::Primitive(primitive) => {
-            format!("{:?}", primitive)
+                .collect::<Result<Vec<String>>>()?;
+            Ok(format!("({})", elements.join(", ")))
         }
+        TypeDef::Primitive(primitive) => Ok(format!("{:?}", primitive)),
         TypeDef::Compact(compact) => {
-            let inner_type = resolve_type(compact.type_param.id, types);
-            format!("Compact<{}>", inner_type)
+            let inner_type = resolve_type(compact.type_param.id, types)?;
+            Ok(format!("Compact<{}>", inner_type))
         }
-        TypeDef::BitSequence(_) => "".to_string(),
+        TypeDef::BitSequence(_) => Ok(String::default()),
     }
 }
 
-fn resolve_type(type_id: u32, types: &PortableRegistry) -> String {
+fn resolve_type(type_id: u32, types: &PortableRegistry) -> Result<String> {
     types
         .resolve(type_id)
         .map(|t| format_type(t, types))
-        .unwrap_or_else(|| "Unknown".to_string())
+        .unwrap_or_else(|| bail!("Invalid metadata"))
 }
 
 fn format_generics(
     params: &[scale_info::TypeParameter<PortableForm>],
     types: &PortableRegistry,
-) -> String {
+) -> Result<String> {
     if params.is_empty() {
-        "".to_string()
+        Ok(String::default())
     } else {
-        let generics: Vec<String> = params
+        let generics = params
             .iter()
             .map(|p| {
                 p.ty.map(|ty| resolve_type(ty.id, types))
-                    .unwrap_or_default()
+                    .unwrap_or_else(|| Ok(String::default()))
             })
-            .collect();
-        format!("<{}>", generics.join(", "))
+            .collect::<Result<Vec<String>>>()?;
+        Ok(format!("<{}>", generics.join(", ")))
+    }
+}
+fn parse_storage_entry(
+    variant: &frame_metadata::v15::StorageEntryMetadata<scale_info::form::PortableForm>,
+    types: &PortableRegistry,
+) -> Result<Storage> {
+    match &variant.ty {
+        StorageEntryType::Map { key, value, .. } => {
+            let type_key = resolve_type(key.id, types)?;
+            let type_value = resolve_type(value.id, types)?;
+            Ok(Storage {
+                documentation: variant.docs.join("\n"),
+                name: variant.name.clone(),
+                type_key,
+                type_value,
+            })
+        }
+        StorageEntryType::Plain(v) => {
+            let type_value = resolve_type(v.id, types)?;
+            let type_value = if let StorageEntryModifier::Optional = &variant.modifier {
+                format!("Option<{}>", type_value)
+            } else {
+                type_value
+            };
+            Ok(Storage {
+                documentation: variant.docs.join("\n"),
+                name: variant.name.clone(),
+                type_key: String::default(),
+                type_value,
+            })
+        }
     }
 }
 
@@ -545,71 +574,39 @@ fn get_from_metadata_v15(
             None
         };
 
-        let storages: Vec<Storage> = pallet
+        let storages = pallet
             .storage
             .map(|storage| {
                 storage
                     .entries
                     .iter()
-                    .map(|variant| {
-                        let resolve_type = |type_id: u32| -> String {
-                            metadata_v15
-                                .types
-                                .resolve(type_id)
-                                .map(|resolved| format_type(resolved, &metadata_v15.types))
-                                .unwrap_or_default()
-                        };
-                        match &variant.ty {
-                            StorageEntryType::Map { key, value, .. } => Storage {
-                                documentation: variant.docs.join("\n"),
-                                name: variant.name.clone(),
-                                type_key: resolve_type(key.id),
-                                type_value: resolve_type(value.id),
-                            },
-                            StorageEntryType::Plain(v) => Storage {
-                                documentation: variant.docs.join("\n"),
-                                name: variant.name.clone(),
-                                type_key: String::default(),
-                                type_value: if let StorageEntryModifier::Optional =
-                                    &variant.modifier
-                                {
-                                    format!("Option<{}>", resolve_type(v.id))
-                                } else {
-                                    resolve_type(v.id)
-                                },
-                            },
-                        }
-                    })
-                    .collect()
+                    .map(|v| parse_storage_entry(v, &metadata_v15.types))
+                    .collect::<Result<Vec<Storage>>>()
             })
-            .unwrap_or_default();
+            .unwrap_or_else(|| {
+                println!("{}: {} (0 storage)", pallet.index, pallet.name);
+                Ok(Vec::default())
+            })?;
 
-        let constants: Vec<Constant> = pallet
+        let constants = pallet
             .constants
             .iter()
             .map(|i| {
-                let resolve_type = |type_id: u32| -> String {
-                    metadata_v15
-                        .types
-                        .resolve(type_id)
-                        .map(|resolved| format_type(resolved, &metadata_v15.types))
-                        .unwrap_or_default()
-                };
-
-                let decode_value = |value: &Vec<u8>, type_id: u32| -> String {
-                    scale_value::scale::decode_as_type(&mut &**value, &type_id, &metadata_v15.types)
-                        .map(|v| v.to_string())
-                        .unwrap_or_default()
-                };
-
-                Constant {
+                let type_value = resolve_type(i.ty.id, &metadata_v15.types)?;
+                let value = scale_value::scale::decode_as_type(
+                    &mut &*i.value,
+                    &i.ty.id,
+                    &metadata_v15.types,
+                )
+                .map_err(|e| anyhow::anyhow!("{}", e))?;
+                Ok(Constant {
                     documentation: i.docs.join("\n"),
                     name: i.name.clone(),
-                    value: decode_value(&i.value, i.ty.id),
-                    type_value: resolve_type(i.ty.id),
-                }
+                    value: value.to_string(),
+                    type_value,
+                })
             })
-            .collect();
+            .collect::<Result<Vec<Constant>>>()?;
 
         let pallet = Pallet::new(
             pallet.index,