Skip to content

Commit fedd44e

Browse files
fix(project-creation): Rollback everything if rules requests fail (#92099)
**Problem** Right now, even if creating a rule fails, the project still gets created — and that’s not ideal. Users might decide not to go through with the project if the rules don’t work, but when they check the projects dashboard, the project is already there (without the rules they set up). That’s confusing and shouldn’t happen. **Solution** It all feels like a single form submission, but under the hood, up to three different requests might be fired to create a project, custom rules and notification rules. This PR updates the logic so that if any of those requests fail inside the try-catch, the project gets deleted. Thanks to the delete cascade constraint, everything linked to the project gets cleaned up too. closes TET-529
1 parent 6243062 commit fedd44e

File tree

1 file changed

+24
-1
lines changed

1 file changed

+24
-1
lines changed

static/app/views/projectInstall/createProject.tsx

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {PlatformIcon} from 'platformicons';
77

88
import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicator';
99
import {openModal} from 'sentry/actionCreators/modal';
10+
import {removeProject} from 'sentry/actionCreators/projects';
1011
import Access from 'sentry/components/acl/access';
1112
import {Alert} from 'sentry/components/core/alert';
1213
import {Button} from 'sentry/components/core/button';
@@ -283,6 +284,8 @@ export function CreateProject() {
283284
return;
284285
}
285286

287+
let projectToRollback: Project | undefined;
288+
286289
try {
287290
const project = await createProject.mutateAsync({
288291
name: projectName,
@@ -291,6 +294,8 @@ export function CreateProject() {
291294
firstTeamSlug: team,
292295
});
293296

297+
projectToRollback = project;
298+
294299
const ruleIds = await createRules({project, alertRuleConfig});
295300

296301
trackAnalytics('project_creation_page.created', {
@@ -351,9 +356,27 @@ export function CreateProject() {
351356
Sentry.captureMessage('Project creation failed');
352357
});
353358
}
359+
360+
if (projectToRollback) {
361+
try {
362+
// Rolling back the project also deletes its associated alert rules
363+
// due to the cascading delete constraint.
364+
await removeProject({
365+
api,
366+
orgSlug: organization.slug,
367+
projectSlug: projectToRollback.slug,
368+
origin: 'getting_started',
369+
});
370+
} catch (err) {
371+
Sentry.withScope(scope => {
372+
scope.setExtra('error', err);
373+
Sentry.captureMessage('Failed to rollback project');
374+
});
375+
}
376+
}
354377
}
355378
},
356-
[createRules, organization, createProject, setCreatedProject, navigate]
379+
[createRules, organization, createProject, setCreatedProject, navigate, api]
357380
);
358381

359382
const handleProjectCreation = useCallback(

0 commit comments

Comments
 (0)