harmony-one / sdk

Javascript SDK of Harmony protocol.
MIT License
92 stars 43 forks source link

Unable to catch errors some errors from the SDK in transactionBase.js #98

Open trekze opened 3 years ago

trekze commented 3 years ago

For some reason I can't seem to gracefully recover from errors thrown in the SDK, despite using the .on("error" handler AND wrapping the send function a try catch block. Any ideas why that's the case? Sample code below:

try {
            let sendoptions = {
                from: from,
                gasLimit: '250000',
                gasPrice: new hmy.utils.Unit(GAS_PRICE_GWEI).asGwei().toWei(),
            };
            await contract.methods
                .transfer(to, new Unit(amount).asOne().toWei())
                .send(sendoptions)
                .on("transactionHash", (_hash) => {
                })
                .on("receipt", (_receipt) => {
                })
                .on("confirmation", (confirmation) => {

                })
                .on("error", (error) => {

                });
        } catch (err) {

        }

And the error that's taking down the process below:

17:33:59: Withdraw: send failure within Harmony, reverting balance for wallet 8271
17:33:59: REJECTED
/path/hidden/node_modules/@harmony-js/transaction/dist/transactionBase.js:202
                        throw new Error("The transaction is still not confirmed after " + maxAttempts + " attempts.");
                              ^

Error: The transaction is still not confirmed after 20 attempts.
    at Transaction.<anonymous> (/path/hidden/node_modules/@harmony-js/transaction/dist/transactionBase.js:202:31)
    at step (/path/hidden/node_modules/tslib/tslib.js:143:27)
    at Object.next (/path/hidden/node_modules/tslib/tslib.js:124:57)
    at fulfilled (/path/hidden/node_modules/tslib/tslib.js:114:62)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
trekze commented 3 years ago

Any chance to get some feedback on the above? Not being able to recover gracefully from an error thrown by the SDK is kind of a deal-breaker, so curious to hear if I'm doing something wrong.

gupadhyaya commented 3 years ago

@hmexx can you try catching error inside .on("confirmation", ... block? looks like sdk emits confirmation (=false) even for the failure case: https://github.com/harmony-one/sdk/blob/master/packages/harmony-transaction/src/transactionBase.ts#L191

trekze commented 3 years ago

@gupadhyaya Hey!

Thanks for getting back to me. What would the above minimal code look like with your suggestion? I'm not super familiar with emitters but as you can see there is already an .on("error, ... in there.

neeboo commented 3 years ago

Hi, @hmexx , can you try this

try {
            let sendoptions = {
                from: from,
                gasLimit: '250000',
                gasPrice: new hmy.utils.Unit(GAS_PRICE_GWEI).asGwei().toWei(),
            };
            const txn= contract.methods
                .transfer(to, new Unit(amount).asOne().toWei())
                .send(sendoptions);

              txn.on("transactionHash", (_hash) => {
                })
                .on("receipt", (_receipt) => {
                })
                .on("confirmation", (confirmation) => {
                 // try throw here?
                })
                .on("error", (error) => {
                  // try throw here?
                });
        await txn;
        } catch (err) {

        }
trekze commented 3 years ago

Hi There!

Thank you for suggesting this fix. I will try it out shortly and report back.

trekze commented 3 years ago

I'm putting your suggestion into production now, although having had a second look at it, I think it might semantically identical to what I had before. Will let you know what happens. Unfortunately these uncaught SDK exceptions are very rare (once every couple weeks) so it might be a while.

neeboo commented 3 years ago

I'm putting your suggestion into production now, although having had a second look at it, I think it might semantically identical to what I had before. Will let you know what happens. Unfortunately these uncaught SDK exceptions are very rare (once every couple weeks) so it might be a while.

They are not identical, since the eventEmitter happens before the Promise, the try catch only knows when the emitter ends. so the await only cares about the Promise, not the emitter itself.

trekze commented 3 years ago

Afraid it didn't work. Exception from the SDK took down the process again:

11:20:07: Withdraw: send failure within Harmony, reverting balance for wallet 11949
11:20:07: REJECTED
/path/node_modules/@harmony-js/network/dist/messenger/messenger.js:82
                            throw new Error(e_1);
                                  ^

Error: FetchError: invalid json response body at https://api.s0.t.hmny.io/ reason: Unexpected end of JSON input
    at Messenger.<anonymous> (/node_modules/@harmony-js/network/dist/messenger/messenger.js:82:35)
    at step (/node_modules/tslib/tslib.js:143:27)
    at Object.throw (/node_modules/tslib/tslib.js:124:57)
    at rejected (/node_modules/tslib/tslib.js:115:69)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

Any ideas?

gupadhyaya commented 3 years ago

Afraid it didn't work. Exception from the SDK took down the process again:

11:20:07: Withdraw: send failure within Harmony, reverting balance for wallet 11949
11:20:07: REJECTED
/path/node_modules/@harmony-js/network/dist/messenger/messenger.js:82
                            throw new Error(e_1);
                                  ^

Error: FetchError: invalid json response body at https://api.s0.t.hmny.io/ reason: Unexpected end of JSON input
    at Messenger.<anonymous> (/node_modules/@harmony-js/network/dist/messenger/messenger.js:82:35)
    at step (/node_modules/tslib/tslib.js:143:27)
    at Object.throw (/node_modules/tslib/tslib.js:124:57)
    at rejected (/node_modules/tslib/tslib.js:115:69)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

Any ideas?

@neeboo @potvik

neeboo commented 3 years ago

Afraid it didn't work. Exception from the SDK took down the process again:

11:20:07: Withdraw: send failure within Harmony, reverting balance for wallet 11949
11:20:07: REJECTED
/path/node_modules/@harmony-js/network/dist/messenger/messenger.js:82
                            throw new Error(e_1);
                                  ^

Error: FetchError: invalid json response body at https://api.s0.t.hmny.io/ reason: Unexpected end of JSON input
    at Messenger.<anonymous> (/node_modules/@harmony-js/network/dist/messenger/messenger.js:82:35)
    at step (/node_modules/tslib/tslib.js:143:27)
    at Object.throw (/node_modules/tslib/tslib.js:124:57)
    at rejected (/node_modules/tslib/tslib.js:115:69)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

Any ideas?

looks like it happened outside the txnBase.

trekze commented 3 years ago

Any ideas?

I guess can bite the bullet and put the SDK in its own process, with a queueing system, but you should probably get to the bottom of this.

Didn't happen for 10 days, but happened twice in the last 48 hours. I guess it depends on the health of the blockchain.

trekze commented 2 years ago

FYI this still happens, although it doesn't kill our process anymore, since we use pm2 to manage the services.