Skip to content

Commit a81cd08

Browse files
Merge pull request #3771 from RedisInsight/be/bugfix/RI-6062-fix-stack-server-error
fix stack server error
2 parents 995016f + f9f6b7c commit a81cd08

File tree

6 files changed

+86
-15
lines changed

6 files changed

+86
-15
lines changed

redisinsight/api/src/modules/feature/repositories/local.features-config.repository.spec.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
mockFeaturesConfigEntity,
77
mockRepository,
88
MockType,
9-
} from 'src/__mocks__';
9+
} from 'src/__mocks__'
1010
import { LocalFeaturesConfigRepository } from 'src/modules/feature/repositories/local.features-config.repository';
1111
import { FeaturesConfigEntity } from 'src/modules/feature/entities/features-config.entity';
1212
import { plainToClass } from 'class-transformer';
@@ -85,6 +85,21 @@ describe('LocalFeaturesConfigRepository', () => {
8585

8686
expect(result).toEqual(mockFeaturesConfig);
8787
});
88+
it('should fail to create with unique constraint and return existing', async () => {
89+
repository.findOneBy.mockResolvedValueOnce(null);
90+
repository.findOneBy.mockResolvedValueOnce(mockFeaturesConfig);
91+
repository.save.mockRejectedValueOnce({ code: 'SQLITE_CONSTRAINT' });
92+
93+
const result = await service.getOrCreate();
94+
95+
expect(result).toEqual(mockFeaturesConfig);
96+
});
97+
it('should fail when failed to create new and error is not unique constraint', async () => {
98+
repository.findOneBy.mockResolvedValueOnce(null);
99+
repository.save.mockRejectedValueOnce(new Error());
100+
101+
await expect(service.getOrCreate()).rejects.toThrow(Error);
102+
});
88103
});
89104

90105
describe('update', () => {

redisinsight/api/src/modules/feature/repositories/local.features-config.repository.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,21 @@ export class LocalFeaturesConfigRepository extends FeaturesConfigRepository {
4343
let entity = await this.repository.findOneBy({ id: this.id });
4444

4545
if (!entity) {
46-
this.logger.log('Creating features config entity');
46+
try {
47+
this.logger.log('Creating features config entity');
4748

48-
entity = await this.repository.save(plainToClass(FeaturesConfigEntity, {
49-
id: this.id,
50-
data: defaultConfig,
51-
controlNumber: this.generateControlNumber(),
52-
}));
49+
entity = await this.repository.save(plainToClass(FeaturesConfigEntity, {
50+
id: this.id,
51+
data: defaultConfig,
52+
controlNumber: this.generateControlNumber(),
53+
}));
54+
} catch (e) {
55+
if (e.code === 'SQLITE_CONSTRAINT') {
56+
return this.getOrCreate();
57+
}
58+
59+
throw e;
60+
}
5361
}
5462

5563
return classToClass(FeaturesConfig, entity);

redisinsight/api/src/modules/settings/repositories/local.agreements.repository.spec.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,29 @@ describe('LocalAgreementsRepository', () => {
5555
data: undefined,
5656
});
5757
});
58+
it('should fail to create with unique constraint and return existing', async () => {
59+
repository.findOneBy.mockResolvedValueOnce(null);
60+
repository.findOneBy.mockResolvedValueOnce(mockAgreements);
61+
repository.save.mockRejectedValueOnce({ code: 'SQLITE_CONSTRAINT' });
62+
63+
const result = await service.getOrCreate();
64+
65+
expect(result).toEqual(mockAgreements);
66+
});
67+
it('should fail when failed to create new and error is not unique constraint', async () => {
68+
repository.findOneBy.mockResolvedValueOnce(null);
69+
repository.save.mockRejectedValueOnce(new Error());
70+
71+
await expect(service.getOrCreate()).rejects.toThrow(Error);
72+
});
5873
});
5974

6075
describe('update', () => {
6176
it('should update agreements', async () => {
6277
const result = await service.update(mockSessionMetadata, mockAgreements);
6378

6479
expect(result).toEqual(mockAgreements);
65-
expect(repository.update).toHaveBeenCalledWith({}, {
80+
expect(repository.save).toHaveBeenCalledWith({
6681
...mockAgreementsEntity,
6782
});
6883
});

redisinsight/api/src/modules/settings/repositories/local.agreements.repository.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,24 @@ export class LocalAgreementsRepository extends AgreementsRepository {
1818
let entity = await this.repository.findOneBy({});
1919

2020
if (!entity) {
21-
entity = await this.repository.save(this.repository.create());
21+
try {
22+
entity = await this.repository.save(this.repository.create({ id: 1 }));
23+
} catch (e) {
24+
if (e.code === 'SQLITE_CONSTRAINT') {
25+
return this.getOrCreate();
26+
}
27+
28+
throw e;
29+
}
2230
}
2331

2432
return classToClass(Agreements, entity);
2533
}
2634

2735
async update(_: SessionMetadata, agreements: Agreements): Promise<Agreements> {
28-
await this.repository.update({}, classToClass(AgreementsEntity, agreements));
36+
const entity = classToClass(AgreementsEntity, agreements);
37+
38+
await this.repository.save(entity);
2939

3040
return this.getOrCreate();
3141
}

redisinsight/api/src/modules/settings/repositories/local.settings.repository.spec.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,29 @@ describe('LocalSettingsRepository', () => {
5050
data: undefined,
5151
});
5252
});
53+
it('should fail to create with unique constraint and return existing', async () => {
54+
repository.findOneBy.mockResolvedValueOnce(null);
55+
repository.findOneBy.mockResolvedValueOnce(mockSettings);
56+
repository.save.mockRejectedValueOnce({ code: 'SQLITE_CONSTRAINT' });
57+
58+
const result = await service.getOrCreate();
59+
60+
expect(result).toEqual(mockSettings);
61+
});
62+
it('should fail when failed to create new and error is not unique constraint', async () => {
63+
repository.findOneBy.mockResolvedValueOnce(null);
64+
repository.save.mockRejectedValueOnce(new Error());
65+
66+
await expect(service.getOrCreate()).rejects.toThrow(Error);
67+
});
5368
});
5469

5570
describe('update', () => {
5671
it('should update settings', async () => {
5772
const result = await service.update(mockSessionMetadata, mockSettings);
5873

5974
expect(result).toEqual(mockSettings);
60-
expect(repository.update).toHaveBeenCalledWith({}, {
61-
...mockSettingsEntity,
62-
});
75+
expect(repository.save).toHaveBeenCalledWith(mockSettingsEntity);
6376
});
6477
});
6578
});

redisinsight/api/src/modules/settings/repositories/local.settings.repository.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,24 @@ export class LocalSettingsRepository extends SettingsRepository {
1818
let entity = await this.repository.findOneBy({});
1919

2020
if (!entity) {
21-
entity = await this.repository.save(this.repository.create());
21+
try {
22+
entity = await this.repository.save(this.repository.create({ id : 1 }));
23+
} catch (e) {
24+
if (e.code === 'SQLITE_CONSTRAINT') {
25+
return this.getOrCreate();
26+
}
27+
28+
throw e;
29+
}
2230
}
2331

2432
return classToClass(Settings, entity);
2533
}
2634

2735
async update(_: SessionMetadata, settings: Settings): Promise<Settings> {
28-
await this.repository.update({}, classToClass(SettingsEntity, settings));
36+
const entity = classToClass(SettingsEntity, settings);
37+
38+
await this.repository.save(entity);
2939

3040
return this.getOrCreate();
3141
}

0 commit comments

Comments
 (0)