Skip to content

Commit c7faf01

Browse files
committed
fix(util): add ServerNotReady to list of connection errors
also refactor isConnectionError to check error name instead of message
1 parent 46029ae commit c7faf01

File tree

6 files changed

+36
-35
lines changed

6 files changed

+36
-35
lines changed

Diff for: packages/cardano-services/test/Program/services/ogmios.test.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,6 @@ describe('Service dependency abstractions', () => {
514514
const failMockServer = createMockOgmiosServer({
515515
healthCheck: { response: { networkSynchronization: 0.999, success: true } },
516516
stateQuery: {
517-
eraSummaries: { response: { failWith: { type: 'connectionError' }, success: false } },
518517
systemStart: { response: { success: true } }
519518
}
520519
});
@@ -539,13 +538,15 @@ describe('Service dependency abstractions', () => {
539538

540539
await node.initialize();
541540
await node.start();
541+
for (const socket of failMockServer.wss.clients) {
542+
socket.close();
543+
}
544+
await serverClosePromise(failMockServer);
542545
await expect(node.eraSummaries()).rejects.toBeInstanceOf(
543546
CardanoNodeErrors.CardanoClientErrors.UnknownResultError
544547
);
545548
expect(dnsResolverMock).toBeCalledTimes(2);
546549
await node.shutdown();
547-
548-
await serverClosePromise(failMockServer);
549550
});
550551

551552
it('should execute a provider operation without to intercept it', async () => {

Diff for: packages/e2e/test/long-running/projector-ogmios-connection.test.ts

+2-16
Original file line numberDiff line numberDiff line change
@@ -91,20 +91,9 @@ describe('projector ogmios connection', () => {
9191

9292
afterEach(() => removePrevent());
9393

94-
it.skip('projector reconnects after a short delay', async () => {
94+
it('projector reconnects after a short delay', async () => {
9595
await killContainer(ogmiosContainer);
9696
await waitProjector();
97-
// This throws because is not able to complete HTTP request
98-
await checkProjector();
99-
});
100-
101-
// Once the problem which prevent the original test to work is solved
102-
// the original test can be un-skipped and this one can be removed
103-
it('projector reconnects after a short delay - alternative', async () => {
104-
await killContainer(ogmiosContainer);
105-
// Add a 10" sleep as a quick workaround for HTTP connection issue
106-
await delay(10_000);
107-
await waitProjector();
10897
await checkProjector();
10998
});
11099

@@ -123,10 +112,7 @@ describe('projector ogmios connection', () => {
123112
await killContainer(stakePoolProjectorContainer);
124113
await waitProjector(true, true);
125114
await removePrevent();
126-
// Once the 'projector reconnects after a short delay' problem is solved
127-
// also remove following line and uncomment next one
128-
await waitProjector(false, true);
129-
// await waitProjector();
115+
await waitProjector();
130116
await checkProjector();
131117
});
132118
});

Diff for: packages/ogmios/test/mocks/mockOgmiosServer.ts

+1-5
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
} from './types';
1414
import { HEALTH_RESPONSE_BODY } from './util';
1515
import { Milliseconds } from '@cardano-sdk/core';
16-
import { Schema, UnknownResultError } from '@cardano-ogmios/client';
16+
import { Schema } from '@cardano-ogmios/client';
1717
import { Server, createServer } from 'http';
1818
import WebSocket from 'ws';
1919
import delay from 'delay';
@@ -152,10 +152,6 @@ const handleQuery = async (query: string, config: MockOgmiosServerConfig, send:
152152
];
153153
} else if (config.stateQuery?.eraSummaries?.response.failWith?.type === 'unknownResultError') {
154154
result = 'unknown';
155-
} else if (config.stateQuery?.eraSummaries?.response.failWith?.type === 'connectionError') {
156-
// This error is never actually returned by the server,
157-
// But is used by cardano-services tests
158-
result = new UnknownResultError({ code: 'ECONNREFUSED' });
159155
} else {
160156
throw new Error('Unknown mock response');
161157
}

Diff for: packages/ogmios/test/mocks/types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export type TxSubmitResponse = {
1717
export type EraSummariesResponse = {
1818
success: boolean;
1919
failWith?: {
20-
type: 'unknownResultError' | 'connectionError';
20+
type: 'unknownResultError';
2121
};
2222
};
2323

Diff for: packages/util/src/network.ts

+9-10
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
/* eslint-disable @typescript-eslint/no-explicit-any */
22

3-
export const connectionErrorCodes = [
3+
const connectionErrorCodes = new Set([
44
'ETIMEDOUT',
55
'ECONNRESET',
66
'ECONNREFUSED',
77
'EPIPE',
88
'ENOTFOUND',
99
'ENETUNREACH',
10-
'EAI_AGAIN',
11-
'WebSocket is closed'
12-
];
10+
'EAI_AGAIN'
11+
]);
1312

14-
export const isConnectionError = (error: any) => {
15-
if (
16-
(error?.code && connectionErrorCodes.includes(error.code)) ||
17-
(error?.message && connectionErrorCodes.some((err) => error.message.includes(err)))
18-
) {
13+
const connectionErrorNames = new Set(['WebSocketClosed', 'ServerNotReady']);
14+
15+
export const isConnectionError = (error: any): boolean => {
16+
if (!error || typeof error !== 'object') return false;
17+
if ((error?.name && connectionErrorNames.has(error.name)) || (error?.code && connectionErrorCodes.has(error.code))) {
1918
return true;
2019
}
21-
return false;
20+
return isConnectionError(error.innerError);
2221
};

Diff for: packages/util/test/network.test.ts

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { isConnectionError } from '../src';
2+
3+
describe('isConnectionError', () => {
4+
it('returns false for an object that does not resemble a connection error', () => {
5+
expect(isConnectionError({})).toBe(false);
6+
});
7+
8+
it('returns true if "code" indicates that it is a connection error', () => {
9+
expect(isConnectionError({ code: 'ECONNREFUSED' })).toBe(true);
10+
});
11+
12+
it('returns true if "name" indicates that it is a connection error', () => {
13+
expect(isConnectionError({ name: 'WebSocketClosed' })).toBe(true);
14+
});
15+
16+
it('returns true if "innerError" is a connection error', () => {
17+
expect(isConnectionError({ innerError: { name: 'WebSocketClosed' } })).toBe(true);
18+
});
19+
});

0 commit comments

Comments
 (0)