mirror of
https://github.com/n8n-io/n8n.git
synced 2026-08-28 09:12:12 +08:00
fix(editor): Show error when eligible reviewers fail to load (#37089)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4715,6 +4715,7 @@
|
||||
"workflowReviews.submitForReview.submit": "Submit",
|
||||
"workflowReviews.submitForReview.error.title": "Workflow couldn't be submitted for review",
|
||||
"workflowReviews.submitForReview.error.save": "Save the workflow and try again.",
|
||||
"workflowReviews.submitForReview.error.loadReviewers": "Couldn't load reviewers",
|
||||
"workflowReviews.updateReview.title": "Submit latest changes to existing review",
|
||||
"workflowReviews.updateReview.description": "This workflow already has an {review}. Submit latest changes to the existing review, to get them approved.",
|
||||
"workflowReviews.updateReview.description.review": "open review",
|
||||
|
||||
+21
-3
@@ -487,15 +487,33 @@ describe('WorkflowSubmitForReviewDialog', () => {
|
||||
expect(getByTestId('workflow-review-submit-button')).toBeEnabled();
|
||||
});
|
||||
|
||||
it('keeps submission blocked when loading the reviewers fails', async () => {
|
||||
vi.mocked(fetchEligibleReviewers).mockRejectedValue(new Error('nope'));
|
||||
it('shows error toast and keeps submission blocked when loading the reviewers fails', async () => {
|
||||
const error = new Error('nope');
|
||||
vi.mocked(fetchEligibleReviewers).mockRejectedValue(error);
|
||||
const { getByTestId, goToStep2 } = await renderDialog();
|
||||
await goToStep2();
|
||||
|
||||
await waitFor(() => expect(mockShowError).toHaveBeenCalledWith(error, expect.any(String)));
|
||||
|
||||
await goToStep2();
|
||||
await userEvent.type(getByTestId('workflow-review-title-input'), 'Review payments');
|
||||
|
||||
expect(getByTestId('workflow-review-submit-button')).toBeDisabled();
|
||||
expect(createWorkflowReviewRequest).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('stays silent when the reviewer load fails after the dialog has closed', async () => {
|
||||
let rejectLoad!: (error: unknown) => void;
|
||||
const pendingLoad = new Promise<never>((_resolve, reject) => {
|
||||
rejectLoad = reject;
|
||||
});
|
||||
vi.mocked(fetchEligibleReviewers).mockReturnValue(pendingLoad);
|
||||
const { rerender, flushSave } = await renderDialog();
|
||||
|
||||
// Close before the in-flight load settles, then let it fail.
|
||||
await rerender({ open: false, workflowId: 'workflow-1', flushSave });
|
||||
rejectLoad(new Error('nope'));
|
||||
await pendingLoad.catch(() => {});
|
||||
|
||||
expect(mockShowError).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
||||
+7
-2
@@ -101,9 +101,10 @@ const loadEligibleReviewers = async () => {
|
||||
});
|
||||
if (sequence !== loadReviewersSequence) return;
|
||||
eligibleReviewers.value = data;
|
||||
} catch {
|
||||
} catch (error) {
|
||||
if (sequence !== loadReviewersSequence) return;
|
||||
eligibleReviewers.value = [];
|
||||
toast.showError(error, i18n.baseText('workflowReviews.submitForReview.error.loadReviewers'));
|
||||
} finally {
|
||||
if (sequence === loadReviewersSequence) isLoadingReviewers.value = false;
|
||||
}
|
||||
@@ -112,7 +113,11 @@ const loadEligibleReviewers = async () => {
|
||||
watch(
|
||||
() => props.open,
|
||||
(isOpen) => {
|
||||
if (!isOpen) return;
|
||||
if (!isOpen) {
|
||||
// Invalidate any in-flight load so it can't toast after the dialog closes.
|
||||
loadReviewersSequence++;
|
||||
return;
|
||||
}
|
||||
|
||||
step.value = 1;
|
||||
reviewTitle.value = '';
|
||||
|
||||
Reference in New Issue
Block a user