From 9fdf927c9b05d33518f3448db4c4dc3e8d202c17 Mon Sep 17 00:00:00 2001 From: Sacha Al Himdani Date: Fri, 3 Oct 2025 10:39:30 +0200 Subject: [PATCH] Handle document mapping conflict error Signed-off-by: Sacha Al Himdani --- pkg/coredata/control_document.go | 28 +++++++++++++++++++++++- pkg/server/api/console/v1/v1_resolver.go | 4 ++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/pkg/coredata/control_document.go b/pkg/coredata/control_document.go index 9d75c401b..04c29a464 100644 --- a/pkg/coredata/control_document.go +++ b/pkg/coredata/control_document.go @@ -16,12 +16,14 @@ package coredata import ( "context" + "errors" "fmt" "maps" "time" "github.com/getprobo/probo/pkg/gid" "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" "go.gearno.de/kit/pg" ) @@ -34,8 +36,17 @@ type ( } ControlDocuments []*ControlDocument + + ErrControlDocumentMappingAlreadyExists struct { + ControlID gid.GID + DocumentID gid.GID + } ) +func (e ErrControlDocumentMappingAlreadyExists) Error() string { + return fmt.Sprintf("control %s is already mapped to document %s", e.ControlID, e.DocumentID) +} + func (cp ControlDocument) Insert( ctx context.Context, conn pg.Conn, @@ -64,7 +75,22 @@ VALUES ( "created_at": cp.CreatedAt, } _, err := conn.Exec(ctx, q, args) - return err + + if err != nil { + var pgErr *pgconn.PgError + if errors.As(err, &pgErr) { + if pgErr.Code == "23505" && pgErr.ConstraintName == "controls_policies_pkey" { + return &ErrControlDocumentMappingAlreadyExists{ + ControlID: cp.ControlID, + DocumentID: cp.DocumentID, + } + } + } + + return fmt.Errorf("cannot insert control document: %w", err) + } + + return nil } func (cp ControlDocument) Delete( diff --git a/pkg/server/api/console/v1/v1_resolver.go b/pkg/server/api/console/v1/v1_resolver.go index dbdedd241..78766c057 100644 --- a/pkg/server/api/console/v1/v1_resolver.go +++ b/pkg/server/api/console/v1/v1_resolver.go @@ -1878,6 +1878,10 @@ func (r *mutationResolver) CreateControlDocumentMapping(ctx context.Context, inp control, document, err := prb.Controls.CreateDocumentMapping(ctx, input.ControlID, input.DocumentID) if err != nil { + var errMappingExists *coredata.ErrControlDocumentMappingAlreadyExists + if errors.As(err, &errMappingExists) { + return nil, errors.New(errMappingExists.Error()) + } panic(fmt.Errorf("cannot create control document mapping: %w", err)) }