Skip to content
This repository has been archived by the owner on Mar 24, 2023. It is now read-only.

Commit

Permalink
Merge pull request #92 from nervosnetwork/improve-error
Browse files Browse the repository at this point in the history
fix: return friendly error when can't find backend script hash
  • Loading branch information
RetricSu authored Dec 3, 2021
2 parents a3e443d + e3c72bb commit e9980bd
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 123 deletions.
53 changes: 53 additions & 0 deletions packages/api-server/src/methods/gw-error.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// From https://github.com/ethereum/evmc/blob/v9.0.0/include/evmc/evmc.h#L212

import abiCoder, { AbiCoder } from "web3-eth-abi";
import { FailedReason } from "../base/types/api";
import { RpcError } from "./error";
import { GW_RPC_REQUEST_ERROR } from "./error-code";
import { LogItem, PolyjuiceSystemLog } from "./types";

export const evmcCodeTypeMapping: {
Expand Down Expand Up @@ -72,6 +75,56 @@ export function parseGwError(error: any): GwErrorDetail {
throw error;
}

export function parseGwRpcError(error: any): void {
const prefix = "JSONRPCError: server error ";
let message: string = error.message;
if (message.startsWith(prefix)) {
const jsonErr = message.slice(prefix.length);
const err = JSON.parse(jsonErr);

const last_log: LogItem | undefined = err.data?.last_log;
if (last_log != null) {
const polyjuiceSystemLog = parsePolyjuiceSystemLog(err.data.last_log);
const return_data = err.data.return_data;

let statusReason = "";
if (return_data !== "0x") {
const abi = abiCoder as unknown as AbiCoder;
statusReason = abi.decodeParameter(
"string",
return_data.substring(10)
) as unknown as string;
}

const failedReason: FailedReason = {
status_code: "0x" + polyjuiceSystemLog.statusCode.toString(16),
status_type:
evmcCodeTypeMapping[polyjuiceSystemLog.statusCode.toString()],
message: statusReason,
};
const data = { failed_reason: failedReason };
const newMessage = `${failedReason.status_type.toLowerCase()}: ${
failedReason.message
}`;
throw new RpcError(err.code, newMessage, data);
}

// can't find backend by script hash error
if (err.message?.startsWith("can't find backend for script_hash")) {
throw new RpcError(err.code, "to address is not a valid contract.");
}

throw new RpcError(err.code, err.message);
}

// connection error
if (message.startsWith("request to")) {
throw new Error(message);
}

throw new RpcError(GW_RPC_REQUEST_ERROR, error.message);
}

export function parsePolyjuiceSystemLog(logItem: LogItem): PolyjuiceSystemLog {
let buf = Buffer.from(logItem.data.slice(2), "hex");
if (buf.length !== 8 + 8 + 16 + 4 + 4) {
Expand Down
90 changes: 20 additions & 70 deletions packages/api-server/src/methods/modules/gw.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import { RPC } from "ckb-js-toolkit";
import { RpcError } from "../error";
import { GW_RPC_REQUEST_ERROR } from "../error-code";
import { parseGwRpcError } from "../gw-error";
import { middleware } from "../validator";
import abiCoder, { AbiCoder } from "web3-eth-abi";
import { LogItem } from "../types";
import { evmcCodeTypeMapping, parsePolyjuiceSystemLog } from "../gw-error";
import { FailedReason } from "../../base/types/api";
import { HexNumber } from "@ckb-lumos/base";

export class Gw {
Expand Down Expand Up @@ -59,7 +54,7 @@ export class Gw {
const result = await this.rpc.gw_ping(...args);
return result;
} catch (error) {
parseError(error);
parseGwRpcError(error);
}
}

Expand All @@ -68,7 +63,7 @@ export class Gw {
const result = await this.rpc.gw_get_tip_block_hash(...args);
return result;
} catch (error) {
parseError(error);
parseGwRpcError(error);
}
}

Expand All @@ -84,7 +79,7 @@ export class Gw {
const result = await this.rpc.gw_get_block_hash(...args);
return result;
} catch (error) {
parseError(error);
parseGwRpcError(error);
}
}

Expand All @@ -98,7 +93,7 @@ export class Gw {
const result = await this.rpc.gw_get_block(...args);
return result;
} catch (error) {
parseError(error);
parseGwRpcError(error);
}
}

Expand All @@ -114,7 +109,7 @@ export class Gw {
const result = await this.rpc.gw_get_block_by_number(...args);
return result;
} catch (error) {
parseError(error);
parseGwRpcError(error);
}
}

Expand All @@ -131,7 +126,7 @@ export class Gw {
const result = await this.rpc.gw_get_balance(...args);
return result;
} catch (error) {
parseError(error);
parseGwRpcError(error);
}
}

Expand All @@ -148,7 +143,7 @@ export class Gw {
const result = await this.rpc.gw_get_storage_at(...args);
return result;
} catch (error) {
parseError(error);
parseGwRpcError(error);
}
}

Expand All @@ -162,7 +157,7 @@ export class Gw {
const result = await this.rpc.gw_get_account_id_by_script_hash(...args);
return result;
} catch (error) {
parseError(error);
parseGwRpcError(error);
}
}

Expand All @@ -179,7 +174,7 @@ export class Gw {
const result = await this.rpc.gw_get_nonce(...args);
return result;
} catch (error) {
parseError(error);
parseGwRpcError(error);
}
}

Expand All @@ -193,7 +188,7 @@ export class Gw {
const result = await this.rpc.gw_get_script(...args);
return result;
} catch (error) {
parseError(error);
parseGwRpcError(error);
}
}

Expand All @@ -209,7 +204,7 @@ export class Gw {
const result = await this.rpc.gw_get_script_hash(...args);
return result;
} catch (error) {
parseError(error);
parseGwRpcError(error);
}
}

Expand All @@ -225,7 +220,7 @@ export class Gw {
const result = await this.rpc.gw_get_data(...args);
return result;
} catch (error) {
parseError(error);
parseGwRpcError(error);
}
}

Expand All @@ -239,7 +234,7 @@ export class Gw {
const result = await this.rpc.gw_get_transaction_receipt(...args);
return result;
} catch (error) {
parseError(error);
parseGwRpcError(error);
}
}

Expand All @@ -253,7 +248,7 @@ export class Gw {
const result = await this.rpc.gw_get_transaction(...args);
return result;
} catch (error) {
parseError(error);
parseGwRpcError(error);
}
}

Expand All @@ -267,7 +262,7 @@ export class Gw {
const result = await this.rpc.gw_execute_l2transaction(...args);
return result;
} catch (error) {
parseError(error);
parseGwRpcError(error);
}
}

Expand All @@ -283,7 +278,7 @@ export class Gw {
const result = await this.rpc.gw_execute_raw_l2transaction(...args);
return result;
} catch (error) {
parseError(error);
parseGwRpcError(error);
}
}

Expand All @@ -297,7 +292,7 @@ export class Gw {
const result = await this.rpc.gw_submit_l2transaction(...args);
return result;
} catch (error) {
parseError(error);
parseGwRpcError(error);
}
}

Expand All @@ -311,7 +306,7 @@ export class Gw {
const result = await this.rpc.gw_submit_withdrawal_request(...args);
return result;
} catch (error) {
parseError(error);
parseGwRpcError(error);
}
}

Expand All @@ -327,56 +322,11 @@ export class Gw {
);
return result;
} catch (error) {
parseError(error);
parseGwRpcError(error);
}
}
}

function parseError(error: any): void {
const prefix = "JSONRPCError: server error ";
let message: string = error.message;
if (message.startsWith(prefix)) {
const jsonErr = message.slice(prefix.length);
const err = JSON.parse(jsonErr);

const last_log: LogItem | undefined = err.data?.last_log;
if (last_log != null) {
const polyjuiceSystemLog = parsePolyjuiceSystemLog(err.data.last_log);
const return_data = err.data.return_data;

let statusReason = "";
if (return_data !== "0x") {
const abi = abiCoder as unknown as AbiCoder;
statusReason = abi.decodeParameter(
"string",
return_data.substring(10)
) as unknown as string;
}

const failedReason: FailedReason = {
status_code: "0x" + polyjuiceSystemLog.statusCode.toString(16),
status_type:
evmcCodeTypeMapping[polyjuiceSystemLog.statusCode.toString()],
message: statusReason,
};
const data = { failed_reason: failedReason };
const newMessage = `${failedReason.status_type.toLowerCase()}: ${
failedReason.message
}`;
throw new RpcError(err.code, newMessage, data);
}

throw new RpcError(err.code, err.message);
}

// connection error
if (message.startsWith("request to")) {
throw new Error(message);
}

throw new RpcError(GW_RPC_REQUEST_ERROR, error.message);
}

function formatHexNumber(
num: HexNumber | undefined | null
): HexNumber | undefined | null {
Expand Down
57 changes: 4 additions & 53 deletions packages/api-server/src/methods/modules/poly.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,9 @@ import { middleware, validators } from "../validator";
import { Hash, HexNumber, Address, HexString } from "@ckb-lumos/base";
import { toHexNumber } from "../../base/types/uint";
import { envConfig } from "../../base/env-config";
import {
InternalError,
InvalidParamsError,
RpcError,
Web3Error,
} from "../error";
import { InternalError, InvalidParamsError, Web3Error } from "../error";
import { Query } from "../../db";
import { isAddressMatch, isShortAddressOnChain } from "../../base/address";
import { GW_RPC_REQUEST_ERROR } from "../error-code";
import {
decodeArgs,
deserializeL2TransactionWithAddressMapping,
Expand All @@ -25,10 +19,7 @@ import {
RawL2TransactionWithAddressMapping,
} from "@polyjuice-provider/godwoken/lib/addressTypes";
import { GodwokenClient } from "@godwoken-web3/godwoken";
import { LogItem } from "../types";
import { evmcCodeTypeMapping, parsePolyjuiceSystemLog } from "../gw-error";
import abiCoder, { AbiCoder } from "web3-eth-abi";
import { FailedReason } from "../../base/types/api";
import { parseGwRpcError } from "../gw-error";

export class Poly {
private query: Query;
Expand Down Expand Up @@ -87,7 +78,7 @@ export class Poly {
await saveAddressMapping(this.query, this.rpc, txWithAddressMapping);
return result;
} catch (error) {
parseError(error);
parseGwRpcError(error);
}
}

Expand All @@ -102,7 +93,7 @@ export class Poly {
await saveAddressMapping(this.query, this.rpc, txWithAddressMapping);
return result;
} catch (error) {
parseError(error);
parseGwRpcError(error);
}
}

Expand Down Expand Up @@ -302,43 +293,3 @@ async function saveAddressMapping(
})
);
}

function parseError(error: any): void {
const prefix = "JSONRPCError: server error ";
let message: string = error.message;
if (message.startsWith(prefix)) {
const jsonErr = message.slice(prefix.length);
const err = JSON.parse(jsonErr);

const last_log: LogItem | undefined = err.data?.last_log;
if (last_log != null) {
const polyjuiceSystemLog = parsePolyjuiceSystemLog(err.data.last_log);
const return_data = err.data.return_data;

let statusReason = "";
if (return_data !== "0x") {
const abi = abiCoder as unknown as AbiCoder;
statusReason = abi.decodeParameter(
"string",
return_data.substring(10)
) as unknown as string;
}

const failedReason: FailedReason = {
status_code: "0x" + polyjuiceSystemLog.statusCode.toString(16),
status_type:
evmcCodeTypeMapping[polyjuiceSystemLog.statusCode.toString()],
message: statusReason,
};
const data = { failed_reason: failedReason };
const newMessage = `${failedReason.status_type.toLowerCase()}: ${
failedReason.message
}`;
throw new RpcError(err.code, newMessage, data);
}

throw new RpcError(err.code, err.message);
}

throw new RpcError(GW_RPC_REQUEST_ERROR, error.message);
}

0 comments on commit e9980bd

Please sign in to comment.