From 3d606dd0e8106007d22d7c2ef44d5052fceb5a64 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 20 Jul 2026 16:01:49 +0000 Subject: [PATCH] Replace ErrCampaignNotDraft with operation-specific errors Use ErrCampaignCannotStart and ErrCampaignCannotUpdate with clear actionable messages instead of a generic draft-status sentinel wrapped in noisy fmt.Errorf chains. Signed-off-by: Cursor Agent Co-authored-by: Bryan FRIMIN --- pkg/accessreview/campaign_service.go | 28 +++---------------- pkg/accessreview/errors.go | 3 +- .../v1/access_review_campaign_resolvers.go | 4 +-- 3 files changed, 8 insertions(+), 27 deletions(-) diff --git a/pkg/accessreview/campaign_service.go b/pkg/accessreview/campaign_service.go index 336e8d396..9e4740936 100644 --- a/pkg/accessreview/campaign_service.go +++ b/pkg/accessreview/campaign_service.go @@ -159,12 +159,7 @@ func (s *Service) UpdateCampaign( } if campaign.Status != coredata.AccessReviewCampaignStatusDraft { - return fmt.Errorf( - "cannot update campaign: status is %s, expected %s: %w", - campaign.Status, - coredata.AccessReviewCampaignStatusDraft, - ErrCampaignNotDraft, - ) + return ErrCampaignCannotUpdate } if req.Name != nil && *req.Name != nil { @@ -247,12 +242,7 @@ func (s *Service) AddCampaignSource( } if campaign.Status != coredata.AccessReviewCampaignStatusDraft { - return fmt.Errorf( - "cannot add scope source: campaign status is %s, expected %s: %w", - campaign.Status, - coredata.AccessReviewCampaignStatusDraft, - ErrCampaignNotDraft, - ) + return ErrCampaignCannotUpdate } source := &coredata.AccessReviewSource{} @@ -301,12 +291,7 @@ func (s *Service) RemoveCampaignSource( } if campaign.Status != coredata.AccessReviewCampaignStatusDraft { - return fmt.Errorf( - "cannot remove scope source: campaign status is %s, expected %s: %w", - campaign.Status, - coredata.AccessReviewCampaignStatusDraft, - ErrCampaignNotDraft, - ) + return ErrCampaignCannotUpdate } campaignSource := &coredata.AccessReviewCampaignSource{} @@ -415,12 +400,7 @@ func (s *Service) StartCampaign( } if campaign.Status != coredata.AccessReviewCampaignStatusDraft { - return fmt.Errorf( - "cannot start campaign: status is %s, expected %s: %w", - campaign.Status, - coredata.AccessReviewCampaignStatusDraft, - ErrCampaignNotDraft, - ) + return ErrCampaignCannotStart } var campaignSources coredata.AccessReviewCampaignSources diff --git a/pkg/accessreview/errors.go b/pkg/accessreview/errors.go index b8f1caea1..c004ba860 100644 --- a/pkg/accessreview/errors.go +++ b/pkg/accessreview/errors.go @@ -24,5 +24,6 @@ import "errors" var ( ErrCampaignMissingSources = errors.New("cannot start campaign: no scope sources configured") - ErrCampaignNotDraft = errors.New("campaign must be in draft status") + ErrCampaignCannotStart = errors.New("cannot start campaign: only draft campaigns can be started") + ErrCampaignCannotUpdate = errors.New("cannot update campaign: only draft campaigns can be updated") ) diff --git a/pkg/server/api/console/v1/access_review_campaign_resolvers.go b/pkg/server/api/console/v1/access_review_campaign_resolvers.go index ec8dcb88d..76be1e5ba 100644 --- a/pkg/server/api/console/v1/access_review_campaign_resolvers.go +++ b/pkg/server/api/console/v1/access_review_campaign_resolvers.go @@ -760,7 +760,7 @@ func (r *mutationResolver) UpdateAccessReviewCampaign(ctx context.Context, input return nil, gqlutils.NotFound(ctx, err) } - if errors.Is(err, accessreview.ErrCampaignNotDraft) { + if errors.Is(err, accessreview.ErrCampaignCannotUpdate) { return nil, gqlutils.Invalid(ctx, err) } @@ -806,7 +806,7 @@ func (r *mutationResolver) StartAccessReviewCampaign(ctx context.Context, input campaign, err := r.accessReview.StartCampaign(ctx, scope, input.AccessReviewCampaignID) if err != nil { if errors.Is(err, accessreview.ErrCampaignMissingSources) || - errors.Is(err, accessreview.ErrCampaignNotDraft) { + errors.Is(err, accessreview.ErrCampaignCannotStart) { return nil, gqlutils.Invalid(ctx, err) }