Show section.method on storage read error (#928)
* Show section.method on storage read error * Update packages/types/src/primitive/StorageKey.ts Co-Authored-By: Amaury Martiny <amaury.martiny@protonmail.com> * Update StorageKey.ts
This commit is contained in:
committed by
Ian He
co-authored by
Amaury Martiny
parent
f9318fe013
commit
022b938f00
@@ -196,7 +196,15 @@ export default class Rpc implements RpcInterface {
|
||||
const base = createType(method.type as string, result);
|
||||
|
||||
if (method.type === 'StorageData') {
|
||||
return this.formatStorageData(params[0] as StorageKey, base, isNull(result));
|
||||
const key = params[0] as StorageKey;
|
||||
|
||||
try {
|
||||
return this.formatStorageData(key, base, isNull(result));
|
||||
} catch (error) {
|
||||
console.error(`Unable to decode storage ${key.section}.${key.method}:`, error.message);
|
||||
|
||||
throw error;
|
||||
}
|
||||
} else if (method.type === 'StorageChangeSet') {
|
||||
// multiple return values (via state.storage subscription), decode the values
|
||||
// one at a time, all based on the query types. Three values can be returned -
|
||||
@@ -204,7 +212,13 @@ export default class Rpc implements RpcInterface {
|
||||
// - null - The storage key is empty (but in the resultset)
|
||||
// - undefined - The storage value is not in the resultset
|
||||
return (params[0] as Vector<StorageKey>).reduce((results, key: StorageKey) => {
|
||||
results.push(this.formatStorageSet(key, base as StorageChangeSet));
|
||||
try {
|
||||
results.push(this.formatStorageSet(key, base as StorageChangeSet));
|
||||
} catch (error) {
|
||||
console.error(`Unable to decode storage ${key.section}.${key.method}:`, error.message);
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
return results;
|
||||
}, [] as Array<Codec | undefined>);
|
||||
|
||||
@@ -11,13 +11,19 @@ import { StorageFunctionMetadata as MetaV4 } from '../Metadata/v4/Storage';
|
||||
|
||||
export interface StorageFunction {
|
||||
(arg?: any): Uint8Array;
|
||||
headKey?: Uint8Array;
|
||||
meta: MetaV4;
|
||||
method: string;
|
||||
section: string;
|
||||
toJSON: () => any;
|
||||
headKey?: Uint8Array;
|
||||
}
|
||||
|
||||
type Decoded = {
|
||||
key?: Uint8Array | string;
|
||||
method?: string;
|
||||
section?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* @name StorageKey
|
||||
* @description
|
||||
@@ -26,27 +32,49 @@ export interface StorageFunction {
|
||||
*/
|
||||
export default class StorageKey extends Bytes {
|
||||
private _meta?: MetaV4;
|
||||
private _method?: string;
|
||||
private _outputType?: string;
|
||||
private _section?: string;
|
||||
|
||||
constructor (value?: AnyU8a | StorageKey | StorageFunction | [StorageFunction, any]) {
|
||||
super(StorageKey.decodeStorageKey(value));
|
||||
const { key, method, section } = StorageKey.decodeStorageKey(value);
|
||||
|
||||
super(key);
|
||||
|
||||
this._meta = StorageKey.getMeta(value as StorageKey);
|
||||
this._method = method;
|
||||
this._outputType = StorageKey.getType(value as StorageKey);
|
||||
this._section = section;
|
||||
}
|
||||
|
||||
static decodeStorageKey (value?: AnyU8a | StorageKey | StorageFunction | [StorageFunction, any]): Uint8Array | string | undefined {
|
||||
if (!value || isU8a(value) || isString(value)) {
|
||||
static decodeStorageKey (value?: AnyU8a | StorageKey | StorageFunction | [StorageFunction, any]): Decoded {
|
||||
if (value instanceof StorageKey) {
|
||||
return {
|
||||
key: value,
|
||||
method: value.method,
|
||||
section: value.section
|
||||
};
|
||||
} else if (!value || isString(value) || isU8a(value)) {
|
||||
// let Bytes handle these inputs
|
||||
return value;
|
||||
return {
|
||||
key: value
|
||||
};
|
||||
} else if (isFunction(value)) {
|
||||
return value();
|
||||
return {
|
||||
key: value(),
|
||||
method: value.method,
|
||||
section: value.section
|
||||
};
|
||||
} else if (Array.isArray(value)) {
|
||||
const [fn, ...arg] = value;
|
||||
const [fn, ...arg]: [StorageFunction, ...Array<any>] = value as any;
|
||||
|
||||
assert(isFunction(fn), 'Expected function input for key construction');
|
||||
|
||||
return (fn as Function)(...arg);
|
||||
return {
|
||||
key: fn(...arg),
|
||||
method: fn.method,
|
||||
section: fn.section
|
||||
};
|
||||
}
|
||||
|
||||
throw new Error(`Unable to convert input ${value} to StorageKey`);
|
||||
@@ -81,16 +109,30 @@ export default class StorageKey extends Bytes {
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The metadata or `null` when not available
|
||||
* @description The metadata or `undefined` when not available
|
||||
*/
|
||||
get meta (): MetaV4 | undefined {
|
||||
return this._meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The key method or `undefined` when not specified
|
||||
*/
|
||||
get method (): string | undefined {
|
||||
return this._method;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The output type, `null` when not available
|
||||
*/
|
||||
get outputType (): string | undefined {
|
||||
return this._outputType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description The key section or `undefined` when not specified
|
||||
*/
|
||||
get section (): string | undefined {
|
||||
return this._section;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user