From 3e6a5385c08bb3d217ac74acf291818b073a9189 Mon Sep 17 00:00:00 2001 From: Aetet Date: Thu, 11 Apr 2024 21:51:22 +0200 Subject: [PATCH 1/4] fix: add logs for transaction failing --- .../src/common/logger/logger-middleware.ts | 28 ++- .../common/logger/logger-overrides.test.ts | 180 +++++++++++++++--- .../sdk/src/common/logger/logger-overrides.ts | 6 +- 3 files changed, 186 insertions(+), 28 deletions(-) diff --git a/packages/sdk/src/common/logger/logger-middleware.ts b/packages/sdk/src/common/logger/logger-middleware.ts index e2ba07eb0..b5b2da264 100644 --- a/packages/sdk/src/common/logger/logger-middleware.ts +++ b/packages/sdk/src/common/logger/logger-middleware.ts @@ -149,12 +149,36 @@ export function getInternalLoggerMiddleware( remoteLogger.raw(dataContainer.getErrorData(wrappedError || err)) } } - return wrappedError ? responsePromise.catch(() => { throw wrappedError }) - : responsePromise + + const returnedPromis = (wrappedError ? responsePromise.catch(() => { throw wrappedError }) + : responsePromise) + + returnedPromis.then(async (tx) => { + + if (tx.transaction.constructor.name === "BlockchainEthereumTransaction") { + try { + await tx.transaction.wait() + // Throw error for testing + // throw new Error('HOHOHO') + await remoteLogger.raw(await dataContainer.getTraceData({ method: replaceMethodPart(callable.name, "wait") })) + } catch(err: any) { + wrappedError = wrapSpecialErrors(err) + await remoteLogger.raw(dataContainer.getErrorData(wrappedError || err, { method: replaceMethodPart(callable.name, "wait") })) + } + } + }).catch((e) => {}) + + return returnedPromis }] } } +function replaceMethodPart(method: string, argForReplace: string): string { + let parts = method.split(".") + parts[parts.length - 1] = argForReplace + return parts.join(".") +} + function isCallable(fn: any): fn is WrappedAdvancedFn { return fn instanceof WrappedAdvancedFn || fn?.constructor?.name === "WrappedAdvancedFn" } diff --git a/packages/sdk/src/common/logger/logger-overrides.test.ts b/packages/sdk/src/common/logger/logger-overrides.test.ts index 5c34f7df5..4c5e12592 100644 --- a/packages/sdk/src/common/logger/logger-overrides.test.ts +++ b/packages/sdk/src/common/logger/logger-overrides.test.ts @@ -19,15 +19,31 @@ import { LogsLevel } from "../../domain" import { MintType } from "../../types/nft/mint/prepare" import { getExecRevertedMessage, isErrorWarning } from "./logger-overrides" + +/* +jest.mock('@rarible/sdk-transaction', () => { // replace with actual path + return { + BlockchainEthereumTransaction: jest.fn().mockImplementation(() => { + return { + // mock properties and methods here + wait: jest.fn().mockImplementation(() => Promise.reject("MLOK error")), + // add other properties and methods as needed + }; + }), + }; + }); + */ + + describe("logger overrides", () => { describe("isErrorWarning", () => { - test("EthereumProviderError (transaction underpriced)", async () => { const err = new EthereumProviderError({ data: null, error: { code: -32603, - message: '[ethjs-query] while formatting outputs from RPC \'{"value":{"code":-32603,"data":{"code":-32000,"message":"transaction underpriced"}}}', + message: + '[ethjs-query] while formatting outputs from RPC \'{"value":{"code":-32603,"data":{"code":-32000,"message":"transaction underpriced"}}}', }, method: "any", }) @@ -55,7 +71,7 @@ describe("logger overrides", () => { { message: "Popup closed" }, { code: 4001 }, ] - test.each(errors)("isInfoLevel test with message=$message and code=$code", (error) => { + test.each(errors)("isInfoLevel test with message=$message and code=$code", error => { const err = new EthereumProviderError({ data: null, error, @@ -71,12 +87,13 @@ describe("logger overrides", () => { }) test("ethers error", () => { - const ethersError = "Error while gas estimation with message cannot estimate gas; transaction may fail or may require manual gas limit [ See: https://links.ethers.org/v5-errors-UNPREDICTABLE_GAS_LIMIT ] (reason=\"execution reverted: Function call not successful\", method=\"estimateGas\", transaction={\"from\":\"0x2Cbc450E04a6379d37F1b85655d1fc09bdA3E6dA\",\"to\":\"0x12b3897a36fDB436ddE2788C06Eff0ffD997066e\",\"data\":\"0x0c53c5" + const ethersError = + 'Error while gas estimation with message cannot estimate gas; transaction may fail or may require manual gas limit [ See: https://links.ethers.org/v5-errors-UNPREDICTABLE_GAS_LIMIT ] (reason="execution reverted: Function call not successful", method="estimateGas", transaction={"from":"0x2Cbc450E04a6379d37F1b85655d1fc09bdA3E6dA","to":"0x12b3897a36fDB436ddE2788C06Eff0ffD997066e","data":"0x0c53c5' expect(getExecRevertedMessage(ethersError)).toEqual("Function call not successful") }) test("RPC error", () => { - const error = "Internal JSON-RPC error.\n{\n \"code\": -32000,\n \"message\": \"execution reverted\"\n}" + const error = 'Internal JSON-RPC error.\n{\n "code": -32000,\n "message": "execution reverted"\n}' expect(getExecRevertedMessage(error)).toEqual(error) }) @@ -96,7 +113,9 @@ describe("logger overrides", () => { }) test("flow proposal key error error", () => { - const error = new Error("[Error Code: 1007] error caused by: 1 error occurred:\\n\\t* checking sequence number failed: [Error Code: 1007] invalid proposal key: public key 0 on account 201362ac764cf16f has sequence number 284, but given 283\\n\\n") + const error = new Error( + "[Error Code: 1007] error caused by: 1 error occurred:\\n\\t* checking sequence number failed: [Error Code: 1007] invalid proposal key: public key 0 on account 201362ac764cf16f has sequence number 284, but given 283\\n\\n", + ) expect(isErrorWarning(error, WalletType.FLOW)).toBeTruthy() }) @@ -105,26 +124,27 @@ describe("logger overrides", () => { const ethereum = new Web3Ethereum({ web3: new Web3(provider) }) const ethereumWallet = new EthereumWallet(ethereum) - const erc721Address = convertEthereumContractAddress("0xF3348949Db80297C78EC17d19611c263fc61f987", Blockchain.ETHEREUM) + const erc721Address = convertEthereumContractAddress( + "0xF3348949Db80297C78EC17d19611c263fc61f987", + Blockchain.ETHEREUM, + ) test("should mint ERC721 token", async () => { const mockLogger = jest.fn() const sdk = createRaribleSdk(ethereumWallet, "development", { apiKey: getAPIKey("development"), - logger: new RemoteLogger( - async (msg: LoggableValue) => mockLogger(msg), - { - initialContext: getSdkContext({ - env: "development", - sessionId: "", - config: { - logs: LogsLevel.ERROR, - }, - }), - dropBatchInterval: 100, - maxByteSize: 5 * 10240, + logger: new RemoteLogger(async (msg: LoggableValue) => mockLogger(msg), { + initialContext: getSdkContext({ + env: "development", + sessionId: "", + config: { + logs: LogsLevel.ERROR, + }, }), + dropBatchInterval: 100, + maxByteSize: 5 * 10240, + }), logs: LogsLevel.ERROR, }) @@ -137,10 +157,12 @@ describe("logger overrides", () => { }) const result = await action.submit({ uri: "ipfs://ipfs/QmfVqzkQcKR1vCNqcZkeVVy94684hyLki7QcVzd9rmjuG5", - creators: [{ - account: sender, - value: 10000, - }], + creators: [ + { + account: sender, + value: 10000, + }, + ], royalties: [], lazyMint: false, supply: 1, @@ -162,6 +184,116 @@ describe("logger overrides", () => { expect(logObject.status).toBe(404) expect(logObject.code).toBe("NETWORK_ERR") }) - }) + test("successful transaction wait", async () => { + const mockLogger = jest.fn() + + const sdk = createRaribleSdk(ethereumWallet, "development", { + apiKey: getAPIKey("development"), + logger: new RemoteLogger(async (msg: LoggableValue) => mockLogger(msg), { + initialContext: getSdkContext({ + env: "development", + sessionId: "", + config: { + logs: LogsLevel.ERROR, + }, + }), + dropBatchInterval: 100, + maxByteSize: 5 * 10240, + }), + logs: LogsLevel.ERROR, + }) + + const senderRaw = wallet.getAddressString() + const sender = convertEthereumToUnionAddress(senderRaw, Blockchain.ETHEREUM) + + try { + const rightAddress = "ETHEREUM:0x5fc5fc8693211d29b53c2923222083a81fced33c" + const action = await sdk.nft.mint.prepare({ + collectionId: toCollectionId(rightAddress), + }) + const result = await action.submit({ + uri: "ipfs://ipfs/QmfVqzkQcKR1vCNqcZkeVVy94684hyLki7QcVzd9rmjuG5", + creators: [ + { + account: sender, + value: 10000, + }, + ], + royalties: [], + lazyMint: false, + supply: 1, + }) + + if (result.type === MintType.ON_CHAIN) { + const transaction = await result.transaction.wait() + expect(transaction.blockchain).toEqual("ETHEREUM") + expect(transaction.hash).toBeTruthy() + } else { + throw new Error("Must be on chain") + } + } catch (e) { } + + await delay(1000) + const trace = mockLogger.mock.calls[0][0][0].level + expect(trace).toBe("TRACE") + }) + test("failed transaction wait", async () => { + const mockLogger = jest.fn() + + const sdk = createRaribleSdk(ethereumWallet, "development", { + apiKey: getAPIKey("development"), + logger: new RemoteLogger(async (msg: LoggableValue) => mockLogger(msg), { + initialContext: getSdkContext({ + env: "development", + sessionId: "", + config: { + logs: LogsLevel.ERROR, + }, + }), + dropBatchInterval: 100, + maxByteSize: 5 * 10240, + }), + logs: LogsLevel.ERROR, + }) + + const senderRaw = wallet.getAddressString() + const sender = convertEthereumToUnionAddress(senderRaw, Blockchain.ETHEREUM) + + try { + const rightAddress = "ETHEREUM:0x5fc5fc8693211d29b53c2923222083a81fced33c" + const action = await sdk.nft.mint.prepare({ + collectionId: toCollectionId(rightAddress), + }) + const result = await action.submit({ + uri: "ipfs://ipfs/QmfVqzkQcKR1vCNqcZkeVVy94684hyLki7QcVzd9rmjuG5", + creators: [ + { + account: sender, + value: 10000, + }, + ], + royalties: [], + lazyMint: false, + supply: 1, + }) + + if (result.type === MintType.ON_CHAIN) { + + const transaction = await result.transaction.wait() + + // const transaction = await result.transaction.wait() + // expect(transaction.blockchain).toEqual("ETHEREUM") + // expect(transaction.hash).toBeTruthy() + } else { + throw new Error("Must be on chain") + } + } catch (e) { } + + await delay(1000) + + const trace = mockLogger.mock.calls + // expect(trace).toBe("TRACE") + }) + }) }) diff --git a/packages/sdk/src/common/logger/logger-overrides.ts b/packages/sdk/src/common/logger/logger-overrides.ts index 9eef53bb9..e2ab9305e 100644 --- a/packages/sdk/src/common/logger/logger-overrides.ts +++ b/packages/sdk/src/common/logger/logger-overrides.ts @@ -164,7 +164,7 @@ export class LoggerDataContainer { } return parsedArgs } - async getTraceData() { + async getTraceData(additionalFields?: Record) { const res = await this.input.responsePromise return { level: LogLevel.TRACE, @@ -174,10 +174,11 @@ export class LoggerDataContainer { args: this.stringifiedArgs, resp: JSON.stringify(res), ...(this.extraFields || {}), + ...(additionalFields || {}), } } - getErrorData(rawError: T) { + getErrorData(rawError: T, additionalFields?: Record) { let data const error = WrappedError.isWrappedError(rawError) ? rawError.error as Error : rawError try { @@ -190,6 +191,7 @@ export class LoggerDataContainer { args: this.stringifiedArgs, requestAddress: undefined as undefined | string, ...(this.extraFields || {}), + ...(additionalFields || {}), } if (error instanceof NetworkError || error?.name === "NetworkError") { data.requestAddress = (error as NetworkError)?.url From de955649adb7dc388ef45420be11c027cc540101 Mon Sep 17 00:00:00 2001 From: Aleksandr Sozinov Date: Fri, 12 Apr 2024 17:42:10 +0700 Subject: [PATCH 2/4] chore: logger test fix --- .../src/common/logger/logger-middleware.ts | 7 ++--- .../common/logger/logger-overrides.test.ts | 31 ++++++++----------- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/packages/sdk/src/common/logger/logger-middleware.ts b/packages/sdk/src/common/logger/logger-middleware.ts index b5b2da264..ffe4ccaa9 100644 --- a/packages/sdk/src/common/logger/logger-middleware.ts +++ b/packages/sdk/src/common/logger/logger-middleware.ts @@ -154,19 +154,16 @@ export function getInternalLoggerMiddleware( : responsePromise) returnedPromis.then(async (tx) => { - - if (tx.transaction.constructor.name === "BlockchainEthereumTransaction") { + if (tx?.transaction?.constructor.name === "BlockchainEthereumTransaction") { try { await tx.transaction.wait() - // Throw error for testing - // throw new Error('HOHOHO') await remoteLogger.raw(await dataContainer.getTraceData({ method: replaceMethodPart(callable.name, "wait") })) } catch(err: any) { wrappedError = wrapSpecialErrors(err) await remoteLogger.raw(dataContainer.getErrorData(wrappedError || err, { method: replaceMethodPart(callable.name, "wait") })) } } - }).catch((e) => {}) + }).catch((_) => {}) return returnedPromis diff --git a/packages/sdk/src/common/logger/logger-overrides.test.ts b/packages/sdk/src/common/logger/logger-overrides.test.ts index 4c5e12592..ace598461 100644 --- a/packages/sdk/src/common/logger/logger-overrides.test.ts +++ b/packages/sdk/src/common/logger/logger-overrides.test.ts @@ -19,20 +19,17 @@ import { LogsLevel } from "../../domain" import { MintType } from "../../types/nft/mint/prepare" import { getExecRevertedMessage, isErrorWarning } from "./logger-overrides" +class BlockchainEthereumTransaction { + async wait(): Promise { return Promise.reject("asd") } +} -/* -jest.mock('@rarible/sdk-transaction', () => { // replace with actual path +jest.mock("@rarible/sdk-transaction", () => { // replace with actual path return { BlockchainEthereumTransaction: jest.fn().mockImplementation(() => { - return { - // mock properties and methods here - wait: jest.fn().mockImplementation(() => Promise.reject("MLOK error")), - // add other properties and methods as needed - }; + return new BlockchainEthereumTransaction() }), - }; - }); - */ + } +}) describe("logger overrides", () => { @@ -184,6 +181,7 @@ describe("logger overrides", () => { expect(logObject.status).toBe(404) expect(logObject.code).toBe("NETWORK_ERR") }) + test("successful transaction wait", async () => { const mockLogger = jest.fn() @@ -238,6 +236,7 @@ describe("logger overrides", () => { const trace = mockLogger.mock.calls[0][0][0].level expect(trace).toBe("TRACE") }) + test("failed transaction wait", async () => { const mockLogger = jest.fn() @@ -279,12 +278,7 @@ describe("logger overrides", () => { }) if (result.type === MintType.ON_CHAIN) { - - const transaction = await result.transaction.wait() - - // const transaction = await result.transaction.wait() - // expect(transaction.blockchain).toEqual("ETHEREUM") - // expect(transaction.hash).toBeTruthy() + await result.transaction.wait() } else { throw new Error("Must be on chain") } @@ -292,8 +286,9 @@ describe("logger overrides", () => { await delay(1000) - const trace = mockLogger.mock.calls - // expect(trace).toBe("TRACE") + const trace = mockLogger.mock.calls[0][0] + const foundCall = trace.find((call: any) => call.method === "nft.mint.prepare.submit.wait") + expect(foundCall).toBeTruthy() }) }) }) From 2fec618264f9b1280e43d8e0a7217c9336077fa3 Mon Sep 17 00:00:00 2001 From: Aetet Date: Fri, 12 Apr 2024 17:21:48 +0200 Subject: [PATCH 3/4] fix: fix tests --- .../common/logger/logger-overrides.test.ts | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/packages/sdk/src/common/logger/logger-overrides.test.ts b/packages/sdk/src/common/logger/logger-overrides.test.ts index ace598461..f1fe23c69 100644 --- a/packages/sdk/src/common/logger/logger-overrides.test.ts +++ b/packages/sdk/src/common/logger/logger-overrides.test.ts @@ -19,19 +19,6 @@ import { LogsLevel } from "../../domain" import { MintType } from "../../types/nft/mint/prepare" import { getExecRevertedMessage, isErrorWarning } from "./logger-overrides" -class BlockchainEthereumTransaction { - async wait(): Promise { return Promise.reject("asd") } -} - -jest.mock("@rarible/sdk-transaction", () => { // replace with actual path - return { - BlockchainEthereumTransaction: jest.fn().mockImplementation(() => { - return new BlockchainEthereumTransaction() - }), - } -}) - - describe("logger overrides", () => { describe("isErrorWarning", () => { test("EthereumProviderError (transaction underpriced)", async () => { @@ -238,6 +225,17 @@ describe("logger overrides", () => { }) test("failed transaction wait", async () => { + class BlockchainEthereumTransaction { + async wait(): Promise { return Promise.reject("asd") } + } + + jest.mock("@rarible/sdk-transaction", () => { // replace with actual path + return { + BlockchainEthereumTransaction: jest.fn().mockImplementation(() => { + return new BlockchainEthereumTransaction() + }), + } + }) const mockLogger = jest.fn() const sdk = createRaribleSdk(ethereumWallet, "development", { From 18e3228008f0cd87a092a9b0e4793929f5541f88 Mon Sep 17 00:00:00 2001 From: Aetet Date: Tue, 16 Apr 2024 15:18:26 +0200 Subject: [PATCH 4/4] fix: fix arguments --- packages/sdk/src/common/logger/logger-middleware.ts | 2 +- packages/sdk/src/common/logger/logger-overrides.test.ts | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/sdk/src/common/logger/logger-middleware.ts b/packages/sdk/src/common/logger/logger-middleware.ts index ffe4ccaa9..6558f5003 100644 --- a/packages/sdk/src/common/logger/logger-middleware.ts +++ b/packages/sdk/src/common/logger/logger-middleware.ts @@ -163,7 +163,7 @@ export function getInternalLoggerMiddleware( await remoteLogger.raw(dataContainer.getErrorData(wrappedError || err, { method: replaceMethodPart(callable.name, "wait") })) } } - }).catch((_) => {}) + }).catch(() => {}) return returnedPromis diff --git a/packages/sdk/src/common/logger/logger-overrides.test.ts b/packages/sdk/src/common/logger/logger-overrides.test.ts index f1fe23c69..c55582075 100644 --- a/packages/sdk/src/common/logger/logger-overrides.test.ts +++ b/packages/sdk/src/common/logger/logger-overrides.test.ts @@ -282,8 +282,6 @@ describe("logger overrides", () => { } } catch (e) { } - await delay(1000) - const trace = mockLogger.mock.calls[0][0] const foundCall = trace.find((call: any) => call.method === "nft.mint.prepare.submit.wait") expect(foundCall).toBeTruthy()