Skip to content

Commit 2d47cfd

Browse files
committed
handle scenario accept comes through twice and the review no longer exists
1 parent 3c15d6e commit 2d47cfd

File tree

3 files changed

+34
-5
lines changed

3 files changed

+34
-5
lines changed

src/database/repos/activeReviewsRepo.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,14 @@ export const activeReviewRepo = {
9595
return mapRowToActiveReview(row);
9696
},
9797

98+
/**
99+
* @returns the review with the given threadId, or undefined if not found
100+
*/
101+
async getReviewByThreadIdOrUndefined(threadId: string): Promise<ActiveReview | undefined> {
102+
const row = await this.getRowByThreadId(threadId);
103+
return row ? mapRowToActiveReview(row) : undefined;
104+
},
105+
98106
/**
99107
* Creates a new active review
100108
* @returns The resulting active review

src/services/ReviewCloser.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,20 @@ import { App } from '@slack/bolt';
55
import { chatService } from '@/services/ChatService';
66
import { ActiveReview } from '@models/ActiveReview';
77
import { closeRequest } from '@/services/RequestService';
8+
import log from '@/utils/log';
89

910
export const reviewCloser = {
1011
async closeReviewIfComplete(app: App, threadId: string): Promise<void> {
11-
const review = await activeReviewRepo.getReviewByThreadIdOrFail(threadId);
12+
const review = await activeReviewRepo.getReviewByThreadIdOrUndefined(threadId);
13+
14+
// Review may have already been closed by another concurrent accept/decline
15+
if (!review) {
16+
log.d(
17+
'reviewCloser.closeReviewIfComplete',
18+
`Review ${threadId} not found - likely already closed by concurrent action`,
19+
);
20+
return;
21+
}
1222

1323
if (isCompleted(review)) {
1424
for (const user of review.pendingReviewers) {

src/services/__tests__/reviewCloser.test.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ describe('reviewCloser', () => {
3838
pendingReviewers: [],
3939
pdfIdentifier: '',
4040
};
41-
activeReviewRepo.getReviewByThreadIdOrFail = jest.fn().mockResolvedValue(review);
41+
activeReviewRepo.getReviewByThreadIdOrUndefined = jest.fn().mockResolvedValue(review);
4242

4343
await reviewCloser.closeReviewIfComplete(app, threadId);
4444

@@ -71,7 +71,7 @@ describe('reviewCloser', () => {
7171
pendingReviewers: [],
7272
pdfIdentifier: '',
7373
};
74-
activeReviewRepo.getReviewByThreadIdOrFail = jest.fn().mockResolvedValue(review);
74+
activeReviewRepo.getReviewByThreadIdOrUndefined = jest.fn().mockResolvedValue(review);
7575

7676
await reviewCloser.closeReviewIfComplete(app, threadId);
7777

@@ -98,7 +98,7 @@ describe('reviewCloser', () => {
9898
pendingReviewers: [{ userId: '123', expiresAt: 1, messageTimestamp: '456' }],
9999
pdfIdentifier: '',
100100
};
101-
activeReviewRepo.getReviewByThreadIdOrFail = jest.fn().mockResolvedValue(review);
101+
activeReviewRepo.getReviewByThreadIdOrUndefined = jest.fn().mockResolvedValue(review);
102102

103103
await reviewCloser.closeReviewIfComplete(app, threadId);
104104

@@ -127,7 +127,7 @@ describe('reviewCloser', () => {
127127
pdfIdentifier: '',
128128
};
129129

130-
activeReviewRepo.getReviewByThreadIdOrFail = jest.fn().mockResolvedValue(review);
130+
activeReviewRepo.getReviewByThreadIdOrUndefined = jest.fn().mockResolvedValue(review);
131131

132132
await reviewCloser.closeReviewIfComplete(app, threadId);
133133

@@ -144,6 +144,17 @@ describe('reviewCloser', () => {
144144
);
145145
expect(activeReviewRepo.remove).toHaveBeenCalledWith(threadId);
146146
});
147+
148+
it('should gracefully handle when review has already been closed by concurrent action', async () => {
149+
const threadId = '111';
150+
activeReviewRepo.getReviewByThreadIdOrUndefined = jest.fn().mockResolvedValue(undefined);
151+
152+
await reviewCloser.closeReviewIfComplete(app, threadId);
153+
154+
expect(chatService.replyToReviewThread).not.toHaveBeenCalled();
155+
expect(activeReviewRepo.remove).not.toHaveBeenCalled();
156+
expect(closeRequest).not.toHaveBeenCalled();
157+
});
147158
});
148159
});
149160

0 commit comments

Comments
 (0)