Open jpablogn opened 1 month ago
Subscribe errors are caught here: https://github.com/solana-labs/solana-web3.js/blob/maintenance/v1.x/src/connection.ts#L6255-L6270
Unsubscribe errors are caught here: https://github.com/solana-labs/solana-web3.js/blob/maintenance/v1.x/src/connection.ts#L6310-L6322
In neither place are these errors surfaced to your application.
It's possible that a check for readyState
could be added to isCurrentConnectionStillActive()
. Could you try that, and send a PR if it works?
All things considered, this subscriptions API and implementation are terminally flawed. We've completely rewritten it in 2.0, and I encourage you to migrate your app now. https://x.com/anza_xyz/status/1819093864394764674
Yes, in fact that is the problem, but I don't know how to solve it.
If the program arrives to the line where is written "// TODO: Maybe add an 'errored' state or a retry limit?"
(lines: 6.316
or 6.265
) it goes to an infinite loop that crash the javascript stack.
I have modified rpc-websocket.ts
to have visibility of readyState
like this:
readyState(){
// websocket CONNECTING (0) or OPEN (1)
return ((this.underlyingSocket?.readyState === 1) || (this.underlyingSocket?.readyState === 0));
}
I have tried three different things without success:
Case 1: Include this piece of code in line 6.193
:
if(!this._rpcWebSocket.readyState()){
this._rpcWebSocket.connect();
return;
}
Case 2. Add it to isCurrentConnectionStillActive()
like this:
const activeWebSocketGeneration = this._rpcWebSocketGeneration;
const isCurrentConnectionStillActive = () => {
return ((activeWebSocketGeneration === this._rpcWebSocketGeneration) && (this._rpcWebSocket.readyState()));
};
Case 3. Add this piece of code in lines 6.316
and 6.265
:
if (!this._rpcWebSocket.readyState()){
return;
}
Running the test npm run test:test-with-live-validator
gives following results:
490 passing (1m)
3 pending
7 failing
310 passing (1m)
3 pending
62 failing
476 passing (1m)
3 pending
21 failing
474 passing (1m)
3 pending
23 failing
Running npm run test:unit:node
gives following results:
471 passing (1s)
Tests not finished
Test not finished
Test not finished
Adding a return
just in line 6311
passes all test successfully but I don't know the real effect (as far as the original code also passes al of them but fails in produccion when doing a websocket call when readyState != 1):
if (e instanceof Error) {
console.error(`${unsubscribeMethod} error:`, e.message);
return;
}
I will test it over a real server because I don't have the knowledge to do the test.
By the way I think lines 6.297-6.299 are repeated and can be deleted: https://github.com/solana-labs/solana-web3.js/blob/maintenance/v1.x/src/connection.ts#L6297-L6304
Using a totaly refactored library means investing lots of hours in learning how it works (take into account that there are not many examples published to use as reference), for a big project may have sense, for an small one may be it is faster to do your own small library instead of trying to learn how such a complex one works (talking from my ignorant point of view).
Thank you.
This in not working fine in my code, it just gives back undefined
.... :)
readyState(){
// websocket CONNECTING (0) or OPEN (1)
return this.underlyingSocket?.readyState;
}
But even in that case, this code:
} catch (e) {
if (e instanceof Error) {
console.error(`${unsubscribeMethod} error:`, e.message);
}
// TODO: Maybe add an 'errored' state or a retry limit?
this._setSubscription(hash, {...subscription, state: 'subscribed'});
console.log(`${`-----> hash: ${aux}, ws.connected: ${this._rpcWebSocketConnected}, ` +
`ws.readyState: ${this._rpcWebSocket.readyState()}, ` +
`isActive: ${isCurrentConnectionStillActive()}`);
await this._updateSubscriptions();
}
prints: true, undefined, true
My app uses connect.onAccountChange() and connect.removeAccountChangeListener() and is keeps open 100-200 subscritions.
Main libraries:
The app crashes when it tries to use subscribe/unsubscribe using onAccountChange()/removeAccountChangeListener() and the Websocket is not with readyState===1.
Fail when trying to subscribe (it goes in an infinite loop with all the accounts handled at that moment):
Fail when trying to unsubscribe (it goes in an infinite loop with all the accounts handled at that moment):
And finally crashes:
As far as WebSocket.readyState is not visible, I have tried to catch the error in different ways but I can't catch it.
Option 1: try-catch
Option 2: catch chained
These errors are in file "rpc-websocket.ts" call and notify reject funcions:
But I think the problem could came from 'connection.ts' which has this piece of code with a no controlled catch, because I can't catch the error:
Few questions open en Solana Stack Exchange: https://solana.stackexchange.com/questions/15643/accountunsubscribe-and-accountsubscribe-error-tried-to-call-a-json-rpc-method-w https://solana.stackexchange.com/questions/15698/solana-web3-js-it-is-not-possible-to-detect-websocket-error
Could it be a bug? How can I handle or catch this error? How can I check websocket.readyStatus to avoid subscribe/unsubscribe when it is not in OPEN or CONNECTING?