diff --git a/src/__test__/integration/client.spec.ts b/src/__test__/integration/client.spec.ts index 12b5f7ea..970aff3b 100644 --- a/src/__test__/integration/client.spec.ts +++ b/src/__test__/integration/client.spec.ts @@ -246,6 +246,23 @@ describe('Typescript usage suite', () => { instruction: 'call %init_peer_id% ("peer" "identify") [] res', }); }); + + it('Should throw correct error when the client tries to send a particle not to the relay', async () => { + // arrange + client = await createClient(); + + // act + const [req, promise] = new RequestFlowBuilder() + .withRawScript('(call "incorrect_peer_id" ("any" "service") [])') + .buildWithErrorHandling(); + + await client.initiateFlow(req); + + // assert + await expect(promise).rejects.toMatch( + 'Particle is expected to be sent to only the single peer (relay which client is connected to)', + ); + }); }); async function callIdentifyOnInitPeerId(client: FluenceClient): Promise { diff --git a/src/internal/ClientImpl.ts b/src/internal/ClientImpl.ts index 3bd6241d..4154e6c4 100644 --- a/src/internal/ClientImpl.ts +++ b/src/internal/ClientImpl.ts @@ -112,7 +112,7 @@ export class ClientImpl implements FluenceClient { request.handler.combineWith(this.aquaCallHandler); this.requests.set(request.id, request); - await this.processRequest(request); + this.processRequest(request); } async executeIncomingParticle(particle: Particle) { @@ -130,7 +130,7 @@ export class ClientImpl implements FluenceClient { await this.processRequest(request); } - private async processRequest(request: RequestFlow): Promise { + private processRequest(request: RequestFlow) { try { this.currentRequestId = request.id; request.execute(this.interpreter, this.connection, this.relayPeerId); diff --git a/src/internal/FluenceConnection.ts b/src/internal/FluenceConnection.ts index 7b85d618..10586e35 100644 --- a/src/internal/FluenceConnection.ts +++ b/src/internal/FluenceConnection.ts @@ -54,6 +54,12 @@ export interface FluenceConnectionOptions { dialTimeout?: number; } +export class VersionIncompatibleError extends Error { + constructor() { + super('Current version of JS SDK is incompatible with the connected Fluence node. Please update JS SDK'); + } +} + export class FluenceConnection { private readonly selfPeerId: PeerId; private node: Peer; @@ -89,7 +95,7 @@ export class FluenceConnection { private async createPeer(options?: FluenceConnectionOptions) { const peerInfo = this.selfPeerId; - const transportKey = Websockets.prototype[Symbol.toStringTag] + const transportKey = Websockets.prototype[Symbol.toStringTag]; this.node = await Peer.create({ peerId: peerInfo, modules: { @@ -100,9 +106,9 @@ export class FluenceConnection { config: { transport: { [transportKey]: { - filter: allow_all - } - } + filter: allow_all, + }, + }, }, dialer: { timeout: options?.dialTimeout, @@ -116,7 +122,13 @@ export class FluenceConnection { log.trace(`dialing to the node with client's address: ` + this.node.peerId.toB58String()); - await this.node.dial(this.address); + try { + await this.node.dial(this.address); + } catch (e) { + if (e.name === 'AggregateError' && e._errors[0].code === 'ERR_ENCRYPTION_FAILED') { + throw new VersionIncompatibleError(); + } + } let _this = this; diff --git a/src/internal/RequestFlow.ts b/src/internal/RequestFlow.ts index f77f218d..440a5f52 100644 --- a/src/internal/RequestFlow.ts +++ b/src/internal/RequestFlow.ts @@ -66,6 +66,7 @@ export class RequestFlow { const interpreterOutcome = this.runInterpreter(interpreter); log.debug('inner interpreter outcome:', { + particleId: this.getParticle()?.id, ret_code: interpreterOutcome.ret_code, error_message: interpreterOutcome.error_message, next_peer_pks: interpreterOutcome.next_peer_pks, @@ -86,25 +87,31 @@ export class RequestFlow { // we only expect a single possible peer id to send particle further if (nextPeers.length > 1) { - throw new Error( - 'Particle is expected to be sent to only the single peer (relay which client is connected to)', - ); + this.throwIncorrectNextPeerPks(nextPeers); } // this peer id must be the relay, the client is connected to if (!relayPeerId || nextPeers[0] !== relayPeerId) { - throw new Error( - 'Particle is expected to be sent to only the single peer (relay which client is connected to)', - ); + this.throwIncorrectNextPeerPks(nextPeers); } if (!connection) { - throw new Error('Cannot send particle: non connected'); + this.raiseError('Cannot send particle: non connected'); } this.sendIntoConnection(connection); } + private throwIncorrectNextPeerPks(nextPeers: PeerIdB58[]) { + this.raiseError( + `Particle is expected to be sent to only the single peer (relay which client is connected to). +particle id: ${this.getParticle()?.id} +next peers: ${nextPeers.join(' ')} +relay peer id: ${this.relayPeerId} +`, + ); + } + async initState(peerId: PeerId): Promise { const id = this.id; let currentTime = Date.now();