Skip to content
This repository was archived by the owner on Jul 10, 2025. It is now read-only.

Commit 8c372cd

Browse files
authored
Improvements (#44)
* Add more detailed information when the particle is sent to incorrect peers * Throwing custom error in case of version incompatibility
1 parent d84d9fd commit 8c372cd

File tree

4 files changed

+50
-14
lines changed

4 files changed

+50
-14
lines changed

src/__test__/integration/client.spec.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,23 @@ describe('Typescript usage suite', () => {
246246
instruction: 'call %init_peer_id% ("peer" "identify") [] res',
247247
});
248248
});
249+
250+
it('Should throw correct error when the client tries to send a particle not to the relay', async () => {
251+
// arrange
252+
client = await createClient();
253+
254+
// act
255+
const [req, promise] = new RequestFlowBuilder()
256+
.withRawScript('(call "incorrect_peer_id" ("any" "service") [])')
257+
.buildWithErrorHandling();
258+
259+
await client.initiateFlow(req);
260+
261+
// assert
262+
await expect(promise).rejects.toMatch(
263+
'Particle is expected to be sent to only the single peer (relay which client is connected to)',
264+
);
265+
});
249266
});
250267

251268
async function callIdentifyOnInitPeerId(client: FluenceClient): Promise<string[]> {

src/internal/ClientImpl.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ export class ClientImpl implements FluenceClient {
112112
request.handler.combineWith(this.aquaCallHandler);
113113
this.requests.set(request.id, request);
114114

115-
await this.processRequest(request);
115+
this.processRequest(request);
116116
}
117117

118118
async executeIncomingParticle(particle: Particle) {
@@ -130,7 +130,7 @@ export class ClientImpl implements FluenceClient {
130130
await this.processRequest(request);
131131
}
132132

133-
private async processRequest(request: RequestFlow): Promise<void> {
133+
private processRequest(request: RequestFlow) {
134134
try {
135135
this.currentRequestId = request.id;
136136
request.execute(this.interpreter, this.connection, this.relayPeerId);

src/internal/FluenceConnection.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ export interface FluenceConnectionOptions {
5454
dialTimeout?: number;
5555
}
5656

57+
export class VersionIncompatibleError extends Error {
58+
constructor() {
59+
super('Current version of JS SDK is incompatible with the connected Fluence node. Please update JS SDK');
60+
}
61+
}
62+
5763
export class FluenceConnection {
5864
private readonly selfPeerId: PeerId;
5965
private node: Peer;
@@ -89,7 +95,7 @@ export class FluenceConnection {
8995

9096
private async createPeer(options?: FluenceConnectionOptions) {
9197
const peerInfo = this.selfPeerId;
92-
const transportKey = Websockets.prototype[Symbol.toStringTag]
98+
const transportKey = Websockets.prototype[Symbol.toStringTag];
9399
this.node = await Peer.create({
94100
peerId: peerInfo,
95101
modules: {
@@ -100,9 +106,9 @@ export class FluenceConnection {
100106
config: {
101107
transport: {
102108
[transportKey]: {
103-
filter: allow_all
104-
}
105-
}
109+
filter: allow_all,
110+
},
111+
},
106112
},
107113
dialer: {
108114
timeout: options?.dialTimeout,
@@ -116,7 +122,13 @@ export class FluenceConnection {
116122

117123
log.trace(`dialing to the node with client's address: ` + this.node.peerId.toB58String());
118124

119-
await this.node.dial(this.address);
125+
try {
126+
await this.node.dial(this.address);
127+
} catch (e) {
128+
if (e.name === 'AggregateError' && e._errors[0].code === 'ERR_ENCRYPTION_FAILED') {
129+
throw new VersionIncompatibleError();
130+
}
131+
}
120132

121133
let _this = this;
122134

src/internal/RequestFlow.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ export class RequestFlow {
6666
const interpreterOutcome = this.runInterpreter(interpreter);
6767

6868
log.debug('inner interpreter outcome:', {
69+
particleId: this.getParticle()?.id,
6970
ret_code: interpreterOutcome.ret_code,
7071
error_message: interpreterOutcome.error_message,
7172
next_peer_pks: interpreterOutcome.next_peer_pks,
@@ -86,25 +87,31 @@ export class RequestFlow {
8687

8788
// we only expect a single possible peer id to send particle further
8889
if (nextPeers.length > 1) {
89-
throw new Error(
90-
'Particle is expected to be sent to only the single peer (relay which client is connected to)',
91-
);
90+
this.throwIncorrectNextPeerPks(nextPeers);
9291
}
9392

9493
// this peer id must be the relay, the client is connected to
9594
if (!relayPeerId || nextPeers[0] !== relayPeerId) {
96-
throw new Error(
97-
'Particle is expected to be sent to only the single peer (relay which client is connected to)',
98-
);
95+
this.throwIncorrectNextPeerPks(nextPeers);
9996
}
10097

10198
if (!connection) {
102-
throw new Error('Cannot send particle: non connected');
99+
this.raiseError('Cannot send particle: non connected');
103100
}
104101

105102
this.sendIntoConnection(connection);
106103
}
107104

105+
private throwIncorrectNextPeerPks(nextPeers: PeerIdB58[]) {
106+
this.raiseError(
107+
`Particle is expected to be sent to only the single peer (relay which client is connected to).
108+
particle id: ${this.getParticle()?.id}
109+
next peers: ${nextPeers.join(' ')}
110+
relay peer id: ${this.relayPeerId}
111+
`,
112+
);
113+
}
114+
108115
async initState(peerId: PeerId): Promise<void> {
109116
const id = this.id;
110117
let currentTime = Date.now();

0 commit comments

Comments
 (0)