From 775e433c2d5d200fc14d8f5b465e1634e2af6fbf Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 10 Aug 2022 18:45:03 +0200 Subject: [PATCH] Create and use BroadcastTxError --- CHANGELOG.md | 3 +++ .../cosmwasm-stargate/src/cosmwasmclient.ts | 5 +++-- packages/stargate/src/index.ts | 1 + packages/stargate/src/stargateclient.spec.ts | 15 ++++++++++--- packages/stargate/src/stargateclient.ts | 22 ++++++++++++++++--- 5 files changed, 38 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0942c23a..a08898a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,8 +24,11 @@ and this project adheres to - @cosmjs/stargate: Add support for `MsgVoteWeighted` (register by default and create Amino JSON converters) ([#1224]). - @cosmjs/stargate: Add Amino JSON support for `MsgCreateVestingAccount`. +- @cosmjs/stargate and @cosmjs/cosmwasm-stargate: Create and use + BroadcastTxError ([#1096]). [#1072]: https://github.com/cosmos/cosmjs/issues/1072 +[#1096]: https://github.com/cosmos/cosmjs/issues/1096 [#1154]: https://github.com/cosmos/cosmjs/issues/1154 [#1176]: https://github.com/cosmos/cosmjs/pull/1176 [#1224]: https://github.com/cosmos/cosmjs/pull/1224 diff --git a/packages/cosmwasm-stargate/src/cosmwasmclient.ts b/packages/cosmwasm-stargate/src/cosmwasmclient.ts index d263a978..433d939f 100644 --- a/packages/cosmwasm-stargate/src/cosmwasmclient.ts +++ b/packages/cosmwasm-stargate/src/cosmwasmclient.ts @@ -7,6 +7,7 @@ import { AuthExtension, BankExtension, Block, + BroadcastTxError, Coin, DeliverTxResponse, IndexedTx, @@ -290,8 +291,8 @@ export class CosmWasmClient { const broadcasted = await this.forceGetTmClient().broadcastTxSync({ tx }); if (broadcasted.code) { - throw new Error( - `Broadcasting transaction failed with code ${broadcasted.code} (codespace: ${broadcasted.codeSpace}). Log: ${broadcasted.log}`, + return Promise.reject( + new BroadcastTxError(broadcasted.code, broadcasted.codeSpace ?? "", broadcasted.log), ); } const transactionId = toHex(broadcasted.hash).toUpperCase(); diff --git a/packages/stargate/src/index.ts b/packages/stargate/src/index.ts index 47d27f6b..816b6005 100644 --- a/packages/stargate/src/index.ts +++ b/packages/stargate/src/index.ts @@ -119,6 +119,7 @@ export { assertIsDeliverTxSuccess, Block, BlockHeader, + BroadcastTxError, DeliverTxResponse, IndexedTx, isDeliverTxFailure, diff --git a/packages/stargate/src/stargateclient.spec.ts b/packages/stargate/src/stargateclient.spec.ts index 6c14a73a..1b937656 100644 --- a/packages/stargate/src/stargateclient.spec.ts +++ b/packages/stargate/src/stargateclient.spec.ts @@ -15,6 +15,7 @@ import { ReadonlyDate } from "readonly-date"; import { assertIsDeliverTxSuccess, + BroadcastTxError, isDeliverTxFailure, isDeliverTxSuccess, PrivateStargateClient, @@ -432,9 +433,17 @@ describe("StargateClient", () => { }); const txRawBytes = Uint8Array.from(TxRaw.encode(txRaw).finish()); - await expectAsync(client.broadcastTx(txRawBytes)).toBeRejectedWithError( - simapp44Enabled() ? /invalid recipient address/i : /Broadcasting transaction failed with code 7/i, - ); + try { + await client.broadcastTx(txRawBytes); + assert(false, "Expected broadcastTx to throw"); + } catch (error: any) { + expect(error).toMatch( + simapp44Enabled() ? /invalid recipient address/i : /Broadcasting transaction failed with code 7/i, + ); + assert(error instanceof BroadcastTxError); + expect(error.code).toEqual(7); + expect(error.codespace).toEqual("sdk"); + } client.disconnect(); }); diff --git a/packages/stargate/src/stargateclient.ts b/packages/stargate/src/stargateclient.ts index c9fda562..8a3888db 100644 --- a/packages/stargate/src/stargateclient.ts +++ b/packages/stargate/src/stargateclient.ts @@ -134,6 +134,24 @@ export function assertIsDeliverTxFailure(result: DeliverTxResponse): void { } } +/** + * An error when broadcasting the transaction. This contains the CheckTx errors + * from the blockchain. Once a transaction is included in a block no BroadcastTxError + * is thrown, even if the execution fails (DeliverTx errors). + */ +export class BroadcastTxError extends Error { + public readonly code: number; + public readonly codespace: string; + public readonly log: string | undefined; + + public constructor(code: number, codespace: string, log: string | undefined) { + super(`Broadcasting transaction failed with code ${code} (codespace: ${codespace}). Log: ${log}`); + this.code = code; + this.codespace = codespace; + this.log = log; + } +} + /** Use for testing only */ export interface PrivateStargateClient { readonly tmClient: Tendermint34Client | undefined; @@ -410,9 +428,7 @@ export class StargateClient { const broadcasted = await this.forceGetTmClient().broadcastTxSync({ tx }); if (broadcasted.code) { return Promise.reject( - new Error( - `Broadcasting transaction failed with code ${broadcasted.code} (codespace: ${broadcasted.codeSpace}). Log: ${broadcasted.log}`, - ), + new BroadcastTxError(broadcasted.code, broadcasted.codeSpace ?? "", broadcasted.log), ); } const transactionId = toHex(broadcasted.hash).toUpperCase();