refactor:don't throw error when adding existing relations#1076
refactor:don't throw error when adding existing relations#1076Aliexe-code wants to merge 4 commits intocloudoperators:mainfrom
Conversation
|
|
||
| return err | ||
| if err != nil { | ||
| if strings.Contains(err.Error(), "Error 1062") || strings.Contains(err.Error(), "Duplicate entry") { |
There was a problem hiding this comment.
Why can't we use this:
_, err := sqlExec(s, query, args, l)
if err != nil {
var mysqlErr *mysql.MySQLError
if errors.As(err, &mysqlErr) && mysqlErr.Number == 1062 {
return nil // duplicate entry
}
return err
}
If the relation already exists, don't throw an error message. This prevents polluting logs with duplicate entry errors Fixes cloudoperators#1057
543078c to
0fe7000
Compare
internal/database/mariadb/service.go
Outdated
|
|
||
| return err | ||
| if err != nil { | ||
| if strings.Contains(err.Error(), "Error 1062") || strings.Contains(err.Error(), "Duplicate entry") { |
There was a problem hiding this comment.
The same errors.As() approach can be used here as well
|
|
||
| return err | ||
| if err != nil { | ||
| if strings.Contains(err.Error(), "Error 1062") || strings.Contains(err.Error(), "Duplicate entry") { |
There was a problem hiding this comment.
The same errors.As() approach can be used here as well
Replace strings.Contains() with errors.As() for more robust MySQL error handling when detecting duplicate entry errors (error code 1062). Addresses reviewer feedback from cloudoperators#1076
|
After looking at this again, I suggest using the DuplicateEntryDatabaseError. Here's an example how to use it. When removing a relation, a duplicate error won't happen, so we don't need to add the check there. There might be a |
…etection Replace strings.Contains() and errors.As() with strings.HasPrefix() for MySQL duplicate entry detection and return DuplicateEntryDatabaseError when a duplicate is detected, following the pattern in component_version.go. This allows handlers to catch and handle duplicate entries gracefully with user-friendly error messages instead of logging raw MySQL errors. Addresses reviewer feedback from cloudoperators#1076
There was a problem hiding this comment.
Pull request overview
This PR aims to make “Add* relation” operations idempotent by avoiding errors/log noise when a relation already exists (Fixes #1057).
Changes:
- Added duplicate-key detection for several relation insert operations.
- Introduced
database.NewDuplicateEntryDatabaseError(...)returns for duplicate relations. - Updated duplicate detection logic in
AddComponentVersionToIssue.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| internal/database/mariadb/support_group.go | Adds duplicate handling in support-group relation insert helpers (currently introduces missing import + still returns an error on duplicates). |
| internal/database/mariadb/service.go | Adds duplicate handling in service relation insert helpers (currently introduces missing import + still returns an error on duplicates). |
| internal/database/mariadb/issue.go | Adjusts duplicate handling for issue ↔ component version relation insert (still returns an error on duplicates). |
Comments suppressed due to low confidence (2)
internal/database/mariadb/support_group.go:13
strings.HasPrefixis used in this file, butstringsis not imported in the import block. This will not compile; add the missingstringsimport (or avoid usingstrings.*).
import (
"fmt"
"github.com/cloudoperators/heureka/internal/database"
"github.com/cloudoperators/heureka/internal/entity"
"github.com/samber/lo"
"github.com/sirupsen/logrus"
)
internal/database/mariadb/service.go:13
strings.HasPrefixis used in this file, butstringsis not imported in the import block. This will not compile; add the missingstringsimport (or avoid usingstrings.*).
import (
"fmt"
"github.com/cloudoperators/heureka/internal/database"
"github.com/cloudoperators/heureka/internal/entity"
"github.com/samber/lo"
"github.com/sirupsen/logrus"
)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if err != nil { | ||
| if strings.HasPrefix(err.Error(), "Error 1062") { | ||
| return database.NewDuplicateEntryDatabaseError(fmt.Sprintf("IssueRepository %d already associated with Service %d", issueRepositoryId, serviceId)) | ||
| } |
There was a problem hiding this comment.
This function still returns a DuplicateEntryDatabaseError on duplicate relations. Per the PR/issue goal (“don't throw error when adding existing relations”), duplicates should be treated as a no-op and return nil here (otherwise callers will continue to handle/log it as an error).
| if err != nil { | ||
| // Replace string-based error detection with proper error type checking | ||
| if strings.Contains(err.Error(), "Error 1062") || strings.Contains(err.Error(), "Duplicate entry") { | ||
| return database.NewDuplicateEntryDatabaseError(fmt.Sprintf("ComponentVersion %d already associated with Issue %d", componentVersionId, issueId)) | ||
| if strings.HasPrefix(err.Error(), "Error 1062") { | ||
| return database.NewDuplicateEntryDatabaseError(fmt.Sprintf("Issue %d already associated with ComponentVersion %d", issueId, componentVersionId)) | ||
| } |
There was a problem hiding this comment.
This function still returns a DuplicateEntryDatabaseError on duplicate relations. Per the PR/issue goal (“don't throw error when adding existing relations”), duplicates should be treated as a no-op and return nil instead; otherwise the handler layer will continue to treat/log this as an error.
| if err != nil { | ||
| if strings.HasPrefix(err.Error(), "Error 1062") { | ||
| return database.NewDuplicateEntryDatabaseError(fmt.Sprintf("Service %d already in SupportGroup %d", serviceId, supportGroupId)) | ||
| } |
There was a problem hiding this comment.
This function still returns a DuplicateEntryDatabaseError on duplicate relations. Per the PR/issue goal (“don't throw error when adding existing relations”), this should be treated as a no-op and return nil instead (or the higher layers will continue logging an error for duplicates).
| if err != nil { | ||
| if strings.HasPrefix(err.Error(), "Error 1062") { | ||
| return database.NewDuplicateEntryDatabaseError(fmt.Sprintf("User %d already in SupportGroup %d", userId, supportGroupId)) | ||
| } |
There was a problem hiding this comment.
This function still returns a DuplicateEntryDatabaseError on duplicate relations. Per the PR/issue goal (“don't throw error when adding existing relations”), this should be treated as a no-op and return nil instead (or the higher layers will continue logging an error for duplicates).
| if err != nil { | ||
| if strings.HasPrefix(err.Error(), "Error 1062") { | ||
| return database.NewDuplicateEntryDatabaseError(fmt.Sprintf("User %d already an owner of Service %d", userId, serviceId)) | ||
| } |
There was a problem hiding this comment.
This function still returns a DuplicateEntryDatabaseError on duplicate relations. Per the PR/issue goal (“don't throw error when adding existing relations”), duplicates should be treated as a no-op and return nil here (otherwise callers will continue to handle/log it as an error).
Title:
refactor: don't throw error when adding existing relations
Description
If the relation already exists, don't throw an error message. This prevents polluting our logs with duplicate entry errors.
Modified 5 Add* functions to return nil instead of error when relation already exists:
What type of PR is this? (check all applicable)
Related Tickets & Documents
Fixes #1057
Added tests?
Changes verified with
go build ./...- existing tests cover this functionality.Added to documentation?
Checklist