diff --git a/packages/neuron-ui/src/services/remote/apiMethodWrapper.ts b/packages/neuron-ui/src/services/remote/apiMethodWrapper.ts index c6623c23d7..d21f8db749 100644 --- a/packages/neuron-ui/src/services/remote/apiMethodWrapper.ts +++ b/packages/neuron-ui/src/services/remote/apiMethodWrapper.ts @@ -1,4 +1,3 @@ -// TODO: use error code interface SuccessFromController { status: 1 result: any @@ -12,6 +11,7 @@ interface FailureFromController { meta?: { [key: string]: string } } } + export type ControllerResponse = SuccessFromController | FailureFromController export const RemoteNotLoadError = { @@ -22,15 +22,7 @@ export const RemoteNotLoadError = { } export const apiMethodWrapper = ( - callControllerMethod: ( - controller: any - ) => ( - params: T - ) => Promise<{ - status: any - result: any - message: { code?: number; content?: string; meta?: { [key: string]: string } } - }> + callControllerMethod: (controller: any) => (params: T) => Promise ) => async (realParams: T): Promise => { if (!window.remote) { return RemoteNotLoadError @@ -44,7 +36,16 @@ export const apiMethodWrapper = ( }, } } - const res = await callControllerMethod(controller)(realParams) + + const res: SuccessFromController | FailureFromController = await callControllerMethod(controller)(realParams) + .then(stringifiedRes => (stringifiedRes ? JSON.parse(stringifiedRes) : stringifiedRes)) + .catch(() => ({ + status: 0, + message: { + content: 'Invalid response format', + }, + })) + if (process.env.NODE_ENV === 'development' && window.localStorage.getItem('log-response')) { console.group('api controller') console.info(JSON.stringify(res, null, 2)) diff --git a/packages/neuron-wallet/src/controllers/api.ts b/packages/neuron-wallet/src/controllers/api.ts index 93d44130d0..8187715338 100644 --- a/packages/neuron-wallet/src/controllers/api.ts +++ b/packages/neuron-wallet/src/controllers/api.ts @@ -17,7 +17,7 @@ import WalletsService from 'services/wallets' import SkipDataAndType from 'services/settings/skip-data-and-type' import { ConnectionStatusSubject } from 'models/subjects/node' import { SystemScriptSubject } from 'models/subjects/system-script' -import { CatchControllerError } from 'decorators/errors' +import { MapApiResponse } from 'decorators' import { ResponseCode } from 'utils/const' import { TransactionWithoutHash } from 'types/cell-types' @@ -27,7 +27,9 @@ import { TransactionWithoutHash } from 'types/cell-types' */ export default class ApiController { // App - public static loadInitData = async () => { + + @MapApiResponse + public static async loadInitData() { const walletsService = WalletsService.getInstance() const networksService = NetworksService.getInstance() const [ @@ -114,69 +116,71 @@ export default class ApiController { return { status: ResponseCode.Success, result: initState } } - public static handleViewError = (error: string) => { + @MapApiResponse + public static handleViewError(error: string) { if (env.isDevMode) { console.error(error) } } + @MapApiResponse public static async contextMenu(params: { type: string; id: string }) { return popContextMenu(params) } // Wallets - @CatchControllerError + @MapApiResponse public static async getAllWallets() { return WalletsController.getAll() } - @CatchControllerError + @MapApiResponse public static async getCurrentWallet() { return WalletsController.getCurrent() } - @CatchControllerError - public static async importMnemonic(params: { name: string, password: string, mnemonic: string }) { + @MapApiResponse + public static async importMnemonic(params: { name: string; password: string; mnemonic: string }) { return WalletsController.importMnemonic(params) } - @CatchControllerError - public static async importKeystore(params: { name: string, password: string, keystorePath: string }) { + @MapApiResponse + public static async importKeystore(params: { name: string; password: string; keystorePath: string }) { return WalletsController.importKeystore(params) } - @CatchControllerError - public static async createWallet(params: { name: string, password: string, mnemonic: string }) { + @MapApiResponse + public static async createWallet(params: { name: string; password: string; mnemonic: string }) { return WalletsController.create(params) } - @CatchControllerError - public static async updateWallet(params: { id: string, password: string, name: string, newPassword?: string }) { - WalletsController.update(params) + @MapApiResponse + public static async updateWallet(params: { id: string; password: string; name: string; newPassword?: string }) { + return WalletsController.update(params) } - @CatchControllerError + @MapApiResponse public static async deleteWallet({ id = '', password = '' }) { return WalletsController.delete({ id, password }) } - @CatchControllerError + @MapApiResponse public static async backupWallet({ id = '', password = '' }) { return WalletsController.backup({ id, password }) } - @CatchControllerError + @MapApiResponse public static async setCurrentWallet(id: string) { return WalletsController.activate(id) } - @CatchControllerError + @MapApiResponse public static async getAddressesByWalletID(id: string) { return WalletsController.getAllAddresses(id) } - @CatchControllerError + @MapApiResponse public static async sendCapacity(params: { id: string walletID: string @@ -191,17 +195,17 @@ export default class ApiController { return WalletsController.sendCapacity(params) } - @CatchControllerError + @MapApiResponse public static async sendTx(params: { walletID: string - tx: TransactionWithoutHash, + tx: TransactionWithoutHash password: string description?: string }) { return WalletsController.sendTx(params) } - @CatchControllerError + @MapApiResponse public static async generateTx(params: { walletID: string items: { @@ -214,12 +218,12 @@ export default class ApiController { return WalletsController.generateTx(params) } - @CatchControllerError + @MapApiResponse public static async computeCycles(params: { walletID: string; capacities: string }) { return WalletsController.computeCycles(params) } - @CatchControllerError + @MapApiResponse public static async updateAddressDescription(params: { walletID: string address: string @@ -230,46 +234,46 @@ export default class ApiController { // Networks - @CatchControllerError + @MapApiResponse public static async getAllNetworks() { return NetworksController.getAll() } - @CatchControllerError + @MapApiResponse public static async createNetwork({ name, remote, type = NetworkType.Normal, chain = 'ckb' }: Network) { return NetworksController.create({ name, remote, type, chain }) } - @CatchControllerError + @MapApiResponse public static async updateNetwork(id: NetworkID, options: Partial) { return NetworksController.update(id, options) } - @CatchControllerError + @MapApiResponse public static async getCurrentNetworkID() { return NetworksController.currentID() } - @CatchControllerError + @MapApiResponse public static async setCurrentNetowrk(id: NetworkID) { return NetworksController.activate(id) } // Transactions - @CatchControllerError + @MapApiResponse public static async getTransactionList( params: Controller.Params.TransactionsByKeywords, ) { return TransactionsController.getAllByKeywords(params) } - @CatchControllerError + @MapApiResponse public static async getTransaction(walletID: string, hash: string) { return TransactionsController.get(walletID, hash) } - @CatchControllerError + @MapApiResponse public static async updateTransactionDescription(params: { hash: string; description: string }) { return TransactionsController.updateDescription(params) } @@ -280,7 +284,7 @@ export default class ApiController { // Misc - @CatchControllerError + @MapApiResponse public static async updateSkipDataAndType(skip: boolean) { return SkipDataAndTypeController.update(skip) } diff --git a/packages/neuron-wallet/src/decorators/index.ts b/packages/neuron-wallet/src/decorators/index.ts index 55b5deea58..3581bbe329 100644 --- a/packages/neuron-wallet/src/decorators/index.ts +++ b/packages/neuron-wallet/src/decorators/index.ts @@ -1,10 +1,10 @@ -import errorDecorators from './errors' +import mappers from './mappers' import validatorDecorators from './validators' -export const { CatchControllerError } = errorDecorators +export const { MapApiResponse } = mappers export const { Validate, Password, Required } = validatorDecorators export default { - ...errorDecorators, + ...mappers, ...validatorDecorators, } diff --git a/packages/neuron-wallet/src/decorators/errors.ts b/packages/neuron-wallet/src/decorators/mappers.ts similarity index 63% rename from packages/neuron-wallet/src/decorators/errors.ts rename to packages/neuron-wallet/src/decorators/mappers.ts index 4c4e345d2f..8907e5dc63 100644 --- a/packages/neuron-wallet/src/decorators/errors.ts +++ b/packages/neuron-wallet/src/decorators/mappers.ts @@ -3,27 +3,27 @@ import logger from 'utils/logger' const NODE_DISCONNECTED_CODE = 104 -export const CatchControllerError = (target: any, name: string, descriptor: PropertyDescriptor) => { +export const MapApiResponse = (target: any, name: string, descriptor: PropertyDescriptor) => { const originalMethod = descriptor.value return { ...descriptor, - async value(...args: any[]) { + async value(...args: any[]): Promise { try { - return await originalMethod(...args) + const res = await originalMethod(...args) + return JSON.stringify(res) } catch (err) { logger.error(`${target.name}.${name}:`, err) if (err.code === 'ECONNREFUSED') { err.code = NODE_DISCONNECTED_CODE } - return { + const res = { status: err.code || ResponseCode.Fail, message: typeof err.message === 'string' ? { content: err.message } : err.message, } + return JSON.stringify(res) } }, } } -export default { - CatchControllerError, -} +export default { MapApiResponse }