Better error reporting for Fragments.
This commit is contained in:
parent
2eb3823de4
commit
7dcefcbf71
@ -70,7 +70,7 @@ function parseParamType(param: string, allowIndexed: boolean): ParseNode {
|
||||
|
||||
let originalParam = param;
|
||||
function throwError(i: number) {
|
||||
throw new Error("unexpected character '" + originalParam[i] + "' at position " + i + " in '" + originalParam + "'");
|
||||
logger.throwArgumentError(`unexpected character at position ${ i }`, "param", param);
|
||||
}
|
||||
param = param.replace(/\s/g, " ");
|
||||
|
||||
@ -207,7 +207,7 @@ function parseParamType(param: string, allowIndexed: boolean): ParseNode {
|
||||
}
|
||||
}
|
||||
|
||||
if (node.parent) { throw new Error("unexpected eof"); }
|
||||
if (node.parent) { logger.throwArgumentError("unexpected eof", "param", param); }
|
||||
|
||||
delete parent.state;
|
||||
|
||||
@ -272,7 +272,9 @@ export class ParamType {
|
||||
readonly _isParamType: boolean;
|
||||
|
||||
constructor(constructorGuard: any, params: any) {
|
||||
if (constructorGuard !== _constructorGuard) { throw new Error("use fromString"); }
|
||||
if (constructorGuard !== _constructorGuard) { logger.throwError("use fromString", Logger.errors.UNSUPPORTED_OPERATION, {
|
||||
operation: "new ParamType()"
|
||||
}); }
|
||||
populate(this, params);
|
||||
|
||||
let match = this.type.match(paramTypeArray);
|
||||
@ -398,7 +400,11 @@ export abstract class Fragment {
|
||||
readonly _isFragment: boolean;
|
||||
|
||||
constructor(constructorGuard: any, params: any) {
|
||||
if (constructorGuard !== _constructorGuard) { throw new Error("use a static from method"); }
|
||||
if (constructorGuard !== _constructorGuard) {
|
||||
logger.throwError("use a static from method", Logger.errors.UNSUPPORTED_OPERATION, {
|
||||
operation: "new Fragment()"
|
||||
});
|
||||
}
|
||||
populate(this, params);
|
||||
|
||||
this._isFragment = true;
|
||||
@ -451,7 +457,7 @@ export abstract class Fragment {
|
||||
return ConstructorFragment.fromString(value.trim());
|
||||
}
|
||||
|
||||
throw new Error("unknown fragment");
|
||||
return logger.throwArgumentError("unsupported fragment", "value", value);
|
||||
}
|
||||
|
||||
static isFragment(value: any): value is Fragment {
|
||||
@ -506,7 +512,9 @@ export class EventFragment extends Fragment {
|
||||
static fromObject(value: JsonFragment | EventFragment): EventFragment {
|
||||
if (EventFragment.isEventFragment(value)) { return value; }
|
||||
|
||||
if (value.type !== "event") { throw new Error("invalid event object - " + value.type); }
|
||||
if (value.type !== "event") {
|
||||
logger.throwArgumentError("invalid event object", "value", value);
|
||||
}
|
||||
|
||||
return new EventFragment(_constructorGuard, {
|
||||
name: verifyIdentifier(value.name),
|
||||
@ -519,7 +527,9 @@ export class EventFragment extends Fragment {
|
||||
static fromString(value: string): EventFragment {
|
||||
|
||||
let match = value.match(regexParen);
|
||||
if (!match) { throw new Error("invalid event: " + value); }
|
||||
if (!match) {
|
||||
logger.throwArgumentError("invalid event string", "value", value);
|
||||
}
|
||||
|
||||
let anonymous = false;
|
||||
match[3].split(" ").forEach((modifier) => {
|
||||
@ -553,10 +563,10 @@ function parseGas(value: string, params: any): string {
|
||||
let comps = value.split("@");
|
||||
if (comps.length !== 1) {
|
||||
if (comps.length > 2) {
|
||||
throw new Error("invalid signature");
|
||||
logger.throwArgumentError("invalid human-readable ABI signature", "value", value);
|
||||
}
|
||||
if (!comps[1].match(/^[0-9]+$/)) {
|
||||
throw new Error("invalid signature gas");
|
||||
logger.throwArgumentError("invalid human-readable aBI signature gas", "value", value);
|
||||
}
|
||||
params.gas = BigNumber.from(comps[1]);
|
||||
return comps[0];
|
||||
@ -597,7 +607,20 @@ function parseModifiers(value: string, params: any): void {
|
||||
});
|
||||
}
|
||||
|
||||
function verifyState(value: any): { constant: boolean, payable: boolean, stateMutability: string } {
|
||||
type StateInputValue = {
|
||||
constant?: boolean;
|
||||
payable?: boolean;
|
||||
stateMutability?: string;
|
||||
type?: string;
|
||||
};
|
||||
|
||||
type StateOutputValue = {
|
||||
constant: boolean;
|
||||
payable: boolean;
|
||||
stateMutability: string;
|
||||
};
|
||||
|
||||
function verifyState(value: StateInputValue): StateOutputValue {
|
||||
let result: any = {
|
||||
constant: false,
|
||||
payable: true,
|
||||
@ -611,7 +634,7 @@ function verifyState(value: any): { constant: boolean, payable: boolean, stateMu
|
||||
result.constant = (result.stateMutability === "view" || result.stateMutability === "pure");
|
||||
if (value.constant != null) {
|
||||
if ((!!value.constant) !== result.constant) {
|
||||
throw new Error("cannot have constant function with mutability " + result.stateMutability);
|
||||
logger.throwArgumentError("cannot have constant function with mutability " + result.stateMutability, "value", value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -619,7 +642,7 @@ function verifyState(value: any): { constant: boolean, payable: boolean, stateMu
|
||||
result.payable = (result.stateMutability === "payable");
|
||||
if (value.payable != null) {
|
||||
if ((!!value.payable) !== result.payable) {
|
||||
throw new Error("cannot have payable function with mutability " + result.stateMutability);
|
||||
logger.throwArgumentError("cannot have payable function with mutability " + result.stateMutability, "value", value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -628,7 +651,7 @@ function verifyState(value: any): { constant: boolean, payable: boolean, stateMu
|
||||
|
||||
// If payable we can assume non-constant; otherwise we can't assume
|
||||
if (value.constant == null && !result.payable && value.type !== "constructor") {
|
||||
throw new Error("unable to determine stateMutability");
|
||||
logger.throwArgumentError("unable to determine stateMutability", "value", value);
|
||||
}
|
||||
|
||||
result.constant = !!value.constant;
|
||||
@ -640,7 +663,7 @@ function verifyState(value: any): { constant: boolean, payable: boolean, stateMu
|
||||
}
|
||||
|
||||
if (result.payable && result.constant) {
|
||||
throw new Error("cannot have constant payable function");
|
||||
logger.throwArgumentError("cannot have constant payable function", "value", value);
|
||||
}
|
||||
|
||||
} else if (value.constant != null) {
|
||||
@ -649,7 +672,7 @@ function verifyState(value: any): { constant: boolean, payable: boolean, stateMu
|
||||
result.stateMutability = (result.constant ? "view": "payable");
|
||||
|
||||
} else if (value.type !== "constructor") {
|
||||
throw new Error("unable to determine stateMutability");
|
||||
logger.throwArgumentError("unable to determine stateMutability", "value", value);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -703,11 +726,13 @@ export class ConstructorFragment extends Fragment {
|
||||
static fromObject(value: ConstructorFragment | JsonFragment): ConstructorFragment {
|
||||
if (ConstructorFragment.isConstructorFragment(value)) { return value; }
|
||||
|
||||
if (value.type !== "constructor") { throw new Error("invalid constructor object - " + value.type); }
|
||||
if (value.type !== "constructor") {
|
||||
logger.throwArgumentError("invalid constructor object", "value", value);
|
||||
}
|
||||
|
||||
let state = verifyState(value);
|
||||
if (state.constant) {
|
||||
throw new Error("constructor cannot be constant");
|
||||
logger.throwArgumentError("constructor cannot be constant", "value", value);
|
||||
}
|
||||
|
||||
return new ConstructorFragment(_constructorGuard, {
|
||||
@ -725,9 +750,9 @@ export class ConstructorFragment extends Fragment {
|
||||
value = parseGas(value, params);
|
||||
|
||||
let parens = value.match(regexParen);
|
||||
if (!parens) { throw new Error("invalid constructor: " + value); }
|
||||
|
||||
if (parens[1].trim() !== "constructor") { throw new Error("invalid constructor"); }
|
||||
if (!parens || parens[1].trim() !== "constructor") {
|
||||
logger.throwArgumentError("invalid constructor string", "value", value);
|
||||
}
|
||||
|
||||
params.inputs = parseParams(parens[2].trim(), false);
|
||||
|
||||
@ -807,7 +832,9 @@ export class FunctionFragment extends ConstructorFragment {
|
||||
static fromObject(value: FunctionFragment | JsonFragment): FunctionFragment {
|
||||
if (FunctionFragment.isFunctionFragment(value)) { return value; }
|
||||
|
||||
if (value.type !== "function") { throw new Error("invalid function object - " + value.type); }
|
||||
if (value.type !== "function") {
|
||||
logger.throwArgumentError("invalid function object", "value", value);
|
||||
}
|
||||
|
||||
let state = verifyState(value);
|
||||
|
||||
@ -828,15 +855,17 @@ export class FunctionFragment extends ConstructorFragment {
|
||||
value = parseGas(value, params);
|
||||
|
||||
let comps = value.split(" returns ");
|
||||
if (comps.length > 2) { throw new Error("invalid function"); }
|
||||
if (comps.length > 2) {
|
||||
logger.throwArgumentError("invalid function string", "value", value);
|
||||
}
|
||||
|
||||
let parens = comps[0].match(regexParen);
|
||||
if (!parens) { throw new Error("invalid signature"); }
|
||||
if (!parens) {
|
||||
logger.throwArgumentError("invalid function signature", "value", value);
|
||||
}
|
||||
|
||||
params.name = parens[1].trim();
|
||||
if (!params.name.match(regexIdentifier)) {
|
||||
throw new Error("invalid identifier: '" + params.name + "'");
|
||||
}
|
||||
if (params.name) { verifyIdentifier(params.name); }
|
||||
|
||||
params.inputs = parseParams(parens[2], false);
|
||||
|
||||
@ -846,7 +875,7 @@ export class FunctionFragment extends ConstructorFragment {
|
||||
if (comps.length > 1) {
|
||||
let returns = comps[1].match(regexParen);
|
||||
if (returns[1].trim() != "" || returns[3].trim() != "") {
|
||||
throw new Error("unexpected tokens");
|
||||
logger.throwArgumentError("unexpected tokens", "value", value);
|
||||
}
|
||||
params.outputs = parseParams(returns[2], false);
|
||||
} else {
|
||||
@ -884,7 +913,7 @@ function verifyType(type: string): string {
|
||||
const regexIdentifier = new RegExp("^[A-Za-z_][A-Za-z0-9_]*$");
|
||||
function verifyIdentifier(value: string): string {
|
||||
if (!value || !value.match(regexIdentifier)) {
|
||||
throw new Error("invalid identifier: '" + value + "'");
|
||||
logger.throwArgumentError(`invalid identifier "${ value }"`, "value", value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@ -909,7 +938,7 @@ function splitNesting(value: string): Array<any> {
|
||||
} else if (c === ")") {
|
||||
depth--;
|
||||
if (depth === -1) {
|
||||
throw new Error("unbalanced parenthsis");
|
||||
logger.throwArgumentError("unbalanced parenthsis", "value", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user