Skip to content

Commit 4a84b07

Browse files
author
Kristiyan Ivanov
authored
Merge branch 'main' into latest
2 parents 42d96e2 + 6eb3207 commit 4a84b07

File tree

23 files changed

+313
-57
lines changed

23 files changed

+313
-57
lines changed

.github/workflows/enforce-branch-name-rules.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ jobs:
1717
"${{ github.head_ref }}" != release/* && \
1818
"${{ github.head_ref }}" != dependabot/* && \
1919
"${{ github.head_ref }}" != latest && \
20-
"${{ github.head_ref }}" != fe && \
21-
"${{ github.head_ref }}" != be && \
22-
"${{ github.head_ref }}" != e2e && \
20+
"${{ github.head_ref }}" != fe/* && \
21+
"${{ github.head_ref }}" != be/* && \
22+
"${{ github.head_ref }}" != e2e/* && \
2323
"${{ github.head_ref }}" != ric/* ]]; then
2424
echo "❌ Pull requests to 'main' are only allowed from 'feature/**', 'bugfix/**', 'release/**', 'dependabot/**', 'latest' or 'ric/**' branches."
2525
exit 1

redisinsight/api/src/constants/custom-error-codes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export enum CustomErrorCodes {
1111
RedisConnectionAuthUnsupported = 10_905,
1212
RedisConnectionSentinelMasterRequired = 10_906,
1313
RedisConnectionIncorrectCertificate = 10_907,
14+
RedisConnectionDefaultUserDisabled = 10_908,
1415

1516
// Cloud API [11001, 11099]
1617
CloudApiInternalServerError = 11_000,

redisinsight/api/src/constants/error-messages.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export default {
4444
`Could not connect to ${url}, please check the CA or Client certificate.`,
4545
INCORRECT_CREDENTIALS: (url) =>
4646
`Could not connect to ${url}, please check the Username or Password.`,
47-
47+
DATABASE_DEFAULT_USER_DISABLED: 'Database does not have default user enabled.',
4848
DATABASE_MANAGEMENT_IS_DISABLED:
4949
'Database connection management is disabled.',
5050
CA_CERT_EXIST: 'This ca certificate name is already in use.',
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export enum DatabaseConnectionEvent {
2+
DatabaseConnectionFailed = 'DatabaseConnectionFailed',
3+
}

redisinsight/api/src/modules/database/providers/database.client.factory.spec.ts

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
mockStandaloneRedisClient,
1111
mockSessionMetadata,
1212
MockRedisClient,
13+
mockEventEmitter,
1314
} from 'src/__mocks__';
1415
import { DatabaseAnalytics } from 'src/modules/database/database.analytics';
1516
import { DatabaseService } from 'src/modules/database/database.service';
@@ -30,8 +31,10 @@ import { RedisClient } from 'src/modules/redis/client';
3031
import { ConnectionType } from 'src/modules/database/entities/database.entity';
3132
import {
3233
RedisConnectionTimeoutException,
33-
RedisConnectionUnauthorizedException,
3434
} from 'src/modules/redis/exceptions/connection';
35+
import { EventEmitter2 } from '@nestjs/event-emitter';
36+
import { DatabaseConnectionEvent } from 'src/modules/database/constants/events';
37+
import { InternalServerErrorException } from '@nestjs/common';
3538

3639
describe('DatabaseClientFactory', () => {
3740
let service: DatabaseClientFactory;
@@ -40,6 +43,7 @@ describe('DatabaseClientFactory', () => {
4043
let redisClientStorage: RedisClientStorage;
4144
let redisClientFactory: LocalRedisClientFactory;
4245
let analytics: MockType<DatabaseAnalytics>;
46+
let eventEmitter: MockType<EventEmitter2>;
4347

4448
beforeEach(async () => {
4549
jest.clearAllMocks();
@@ -72,6 +76,10 @@ describe('DatabaseClientFactory', () => {
7276
provide: NodeRedisConnectionStrategy,
7377
useFactory: mockNodeRedisConnectionStrategy,
7478
},
79+
{
80+
provide: EventEmitter2,
81+
useValue: mockEventEmitter,
82+
},
7583
],
7684
}).compile();
7785

@@ -81,6 +89,7 @@ describe('DatabaseClientFactory', () => {
8189
redisClientStorage = await module.get(RedisClientStorage);
8290
redisClientFactory = await module.get(RedisClientFactory);
8391
analytics = await module.get(DatabaseAnalytics);
92+
eventEmitter = await module.get(EventEmitter2);
8493
});
8594

8695
describe('getOrCreateClient', () => {
@@ -247,7 +256,8 @@ describe('DatabaseClientFactory', () => {
247256
},
248257
);
249258
});
250-
it('should throw original error', async () => {
259+
260+
it('should throw original error and emit connection failed event for RedisConnection* errors', async () => {
251261
jest
252262
.spyOn(redisClientFactory, 'createClient')
253263
.mockRejectedValue(new RedisConnectionTimeoutException());
@@ -259,6 +269,27 @@ describe('DatabaseClientFactory', () => {
259269
mockDatabase,
260270
new RedisConnectionTimeoutException(),
261271
);
272+
273+
expect(eventEmitter.emit).toHaveBeenCalledWith(
274+
DatabaseConnectionEvent.DatabaseConnectionFailed,
275+
mockCommonClientMetadata,
276+
);
277+
});
278+
279+
it('should throw original error and not emit connection failed when not RedisConnection* errors', async () => {
280+
jest
281+
.spyOn(redisClientFactory, 'createClient')
282+
.mockRejectedValue(new InternalServerErrorException());
283+
await expect(
284+
service.createClient(mockCommonClientMetadata),
285+
).rejects.toThrow(InternalServerErrorException);
286+
expect(analytics.sendConnectionFailedEvent).toHaveBeenCalledWith(
287+
mockSessionMetadata,
288+
mockDatabase,
289+
new InternalServerErrorException(),
290+
);
291+
292+
expect(eventEmitter.emit).not.toHaveBeenCalled();
262293
});
263294
});
264295
});

redisinsight/api/src/modules/database/providers/database.client.factory.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { Injectable, Logger } from '@nestjs/common';
2-
import { getRedisConnectionException } from 'src/utils';
32
import { DatabaseRepository } from 'src/modules/database/repositories/database.repository';
43
import { DatabaseAnalytics } from 'src/modules/database/database.analytics';
54
import { DatabaseService } from 'src/modules/database/database.service';
@@ -11,6 +10,9 @@ import {
1110
RedisClientFactory,
1211
} from 'src/modules/redis/redis.client.factory';
1312
import { RedisClientStorage } from 'src/modules/redis/redis.client.storage';
13+
import { RedisConnectionFailedException } from 'src/modules/redis/exceptions/connection';
14+
import { EventEmitter2 } from '@nestjs/event-emitter';
15+
import { DatabaseConnectionEvent } from 'src/modules/database/constants/events';
1416

1517
type IsClientConnectingMap = {
1618
[key: string]: boolean;
@@ -37,6 +39,7 @@ export class DatabaseClientFactory {
3739
private readonly analytics: DatabaseAnalytics,
3840
private readonly redisClientStorage: RedisClientStorage,
3941
private readonly redisClientFactory: RedisClientFactory,
42+
private readonly eventEmitter: EventEmitter2,
4043
) {}
4144

4245
private async processGetClient(
@@ -156,6 +159,13 @@ export class DatabaseClientFactory {
156159
} catch (error) {
157160
this.logger.error('Failed to create database client', error);
158161

162+
if (error instanceof RedisConnectionFailedException) {
163+
this.eventEmitter.emit(
164+
DatabaseConnectionEvent.DatabaseConnectionFailed,
165+
clientMetadata,
166+
);
167+
}
168+
159169
this.analytics.sendConnectionFailedEvent(
160170
clientMetadata.sessionMetadata,
161171
database,

redisinsight/api/src/modules/redis/exceptions/connection/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export * from './redis-connection-auth-unsupported.exception';
22
export * from './redis-connection-cluster-nodes-unavailable.exception';
3+
export * from './redis-connection-default-user-disabled.exception';
34
export * from './redis-connection-failed.exception';
45
export * from './redis-connection-incorrect-certificate.exception';
56
export * from './redis-connection-sentinel-master-required.exception';
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { HttpExceptionOptions } from '@nestjs/common';
2+
import { CustomErrorCodes } from 'src/constants';
3+
import ERROR_MESSAGES from 'src/constants/error-messages';
4+
import {
5+
RedisConnectionFailedException,
6+
RedisConnectionFailedStatusCode,
7+
} from 'src/modules/redis/exceptions/connection/redis-connection-failed.exception';
8+
9+
export class RedisConnectionDefaultUserDisabledException extends RedisConnectionFailedException {
10+
constructor(
11+
message: string = ERROR_MESSAGES.DATABASE_DEFAULT_USER_DISABLED,
12+
options?: HttpExceptionOptions,
13+
) {
14+
super({
15+
message,
16+
error: 'RedisConnectionDefaultUserDisabledException',
17+
statusCode: RedisConnectionFailedStatusCode,
18+
errorCode: CustomErrorCodes.RedisConnectionDefaultUserDisabled,
19+
}, options);
20+
}
21+
}

redisinsight/ui/src/components/side-panels/panels/ai-assistant/components/assistance-chat/AssistanceChat.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ const AssistanceChat = () => {
7676
...generateHumanMessage(message),
7777
error: {
7878
statusCode: 500,
79-
errorCode: CustomErrorCodes.GeneralAiUnexpectedError,
79+
errorCode: CustomErrorCodes.QueryAiInternalServerError,
8080
},
8181
}),
8282
)

0 commit comments

Comments
 (0)