Skip to content

Commit bd59245

Browse files
committed
fix(mongodb): check duplicate value error when updating a document
1 parent 1388999 commit bd59245

7 files changed

Lines changed: 97 additions & 25 deletions

File tree

go.sum

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,6 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
246246
gorm.io/driver/sqlite v1.4.4 h1:gIufGoR0dQzjkyqDyYSCvsYR6fba1Gw5YKDqKeChxFc=
247247
gorm.io/driver/sqlite v1.4.4/go.mod h1:0Aq3iPO+v9ZKbcdiz8gLWRw5VOPcBOPUQJFLq5e2ecI=
248248
gorm.io/gorm v1.24.0/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
249-
gorm.io/gorm v1.25.8 h1:WAGEZ/aEcznN4D03laj8DKnehe1e9gYQAjW8xyPRdeo=
250-
gorm.io/gorm v1.25.8/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
251249
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
252250
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
253251
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=

internal/pkg/service/env/database.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@ import (
66

77
var (
88
DatabaseMongoDBURI, DatabaseMongoDBName string
9-
)
109

11-
var (
1210
DatabaseSQLiteDSN string
1311
)
1412

pkg/context/shared/infrastructure/persistences/mongodb/mongodb.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,11 @@ func Close(ctx context.Context, session *Database) error {
6060
return nil
6161
}
6262

63-
func HandleDuplicateKeyError(err error) error {
63+
func IsErrDuplicateValue(err error) bool {
64+
return mongo.IsDuplicateKeyError(err)
65+
}
66+
67+
func HandleErrDuplicateValue(err error) error {
6468
re := regexp.MustCompile(`{ [A-Za-z0-9]+:`)
6569

6670
rawField := re.FindString(err.Error())
@@ -75,7 +79,7 @@ func HandleDuplicateKeyError(err error) error {
7579
}
7680

7781
return errors.New[errors.AlreadyExist](&errors.Bubble{
78-
Where: "HandleDuplicateKeyError",
82+
Where: "HandleErrDuplicateValue",
7983
What: fmt.Sprintf("%s already registered", field),
8084
Why: errors.Meta{
8185
"Field": field,
@@ -84,9 +88,13 @@ func HandleDuplicateKeyError(err error) error {
8488
})
8589
}
8690

87-
func HandleDocumentNotFound(index string, err error) error {
91+
func IsErrNotFound(err error) bool {
92+
return err != nil
93+
}
94+
95+
func HandleErrNotFound(err error, index string) error {
8896
return errors.New[errors.NotExist](&errors.Bubble{
89-
Where: "HandleDocumentNotFound",
97+
Where: "HandleErrNotFound",
9098
What: fmt.Sprintf("%s not found", index),
9199
Why: errors.Meta{
92100
"Index": index,

pkg/context/user/application/update/handler_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,11 @@ func (s *UpdateTestSuite) TestHandle() {
6262

6363
s.hashing.On("IsNotEqual", registered.CipherPassword.Value, aggregate.PlainPassword.Value).Return(false)
6464

65-
hashed := user.CipherPasswordWithValidValue().Value
65+
hashed := user.CipherPasswordWithValidValue()
6666

67-
s.hashing.On("Hash", attributes.UpdatedPassword).Return(hashed)
67+
s.hashing.On("Hash", attributes.UpdatedPassword).Return(hashed.Value)
6868

69-
aggregate.CipherPassword, err = user.NewCipherPassword(hashed)
69+
aggregate.CipherPassword = hashed
7070

7171
s.NoError(err)
7272

pkg/context/user/infrastructure/persistence/mongodb/collection/collection.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ func (c *Collection) Create(user *user.User) error {
2323
_, err := c.Collection.InsertOne(context.Background(), aggregate)
2424

2525
switch {
26-
case mongo.IsDuplicateKeyError(err):
27-
return errors.BubbleUp(mongodb.HandleDuplicateKeyError(err), "Create")
26+
case mongodb.IsErrDuplicateValue(err):
27+
return errors.BubbleUp(mongodb.HandleErrDuplicateValue(err), "Create")
2828
case err != nil:
2929
return errors.New[errors.Internal](&errors.Bubble{
3030
Where: "Create",
@@ -69,7 +69,10 @@ func (c *Collection) Update(user *user.User) error {
6969

7070
_, err := c.Collection.ReplaceOne(context.Background(), filter, aggregate)
7171

72-
if err != nil {
72+
switch {
73+
case mongodb.IsErrDuplicateValue(err):
74+
return errors.BubbleUp(mongodb.HandleErrDuplicateValue(err), "Update")
75+
case err != nil:
7376
return errors.New[errors.Internal](&errors.Bubble{
7477
Where: "Update",
7578
What: "Failure to update a User",
@@ -119,13 +122,15 @@ func (c *Collection) Search(criteria *repository.SearchCriteria) (*user.User, er
119122

120123
result := c.Collection.FindOne(context.Background(), filter)
121124

122-
if err := result.Err(); err != nil {
123-
return nil, mongodb.HandleDocumentNotFound(index, err)
125+
err := result.Err()
126+
127+
if mongodb.IsErrNotFound(err) {
128+
return nil, mongodb.HandleErrNotFound(err, index)
124129
}
125130

126131
primitive := new(user.Primitive)
127132

128-
err := result.Decode(primitive)
133+
err = result.Decode(primitive)
129134

130135
if err != nil {
131136
return nil, errors.New[errors.Internal](&errors.Bubble{

pkg/context/user/infrastructure/persistence/mongodb/collection/collection_test.go

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,14 @@ func (s *CollectionTestSuite) TestCreate() {
5454
s.Equal(expected, actual)
5555
}
5656

57-
func (s *CollectionTestSuite) TestCreateErrDuplicateKey() {
57+
func (s *CollectionTestSuite) TestCreateErrDuplicateValue() {
58+
registered := user.RandomPrimitive()
59+
5860
aggregate := user.RandomPrimitive()
5961

60-
s.NoError(s.sut.Create(aggregate))
62+
s.NoError(s.sut.Create(registered))
63+
64+
aggregate.ID = registered.ID
6165

6266
err := s.sut.Create(aggregate)
6367

@@ -67,7 +71,7 @@ func (s *CollectionTestSuite) TestCreateErrDuplicateKey() {
6771

6872
expected := &errors.AlreadyExist{Bubble: &errors.Bubble{
6973
When: actual.When,
70-
Where: "HandleDuplicateKeyError",
74+
Where: "HandleErrDuplicateValue",
7175
What: "ID already registered",
7276
Why: errors.Meta{
7377
"Field": "ID",
@@ -116,6 +120,36 @@ func (s *CollectionTestSuite) TestUpdate() {
116120
s.Equal(expected, actual)
117121
}
118122

123+
func (s *CollectionTestSuite) TestUpdateErrDuplicateValue() {
124+
registered := user.RandomPrimitive()
125+
126+
aggregate := user.RandomPrimitive()
127+
128+
s.NoError(s.sut.Create(registered))
129+
130+
s.NoError(s.sut.Create(aggregate))
131+
132+
aggregate.Email = registered.Email
133+
134+
err := s.sut.Update(aggregate)
135+
136+
var actual *errors.AlreadyExist
137+
138+
s.ErrorAs(err, &actual)
139+
140+
expected := &errors.AlreadyExist{Bubble: &errors.Bubble{
141+
When: actual.When,
142+
Where: "HandleErrDuplicateValue",
143+
What: "Email already registered",
144+
Why: errors.Meta{
145+
"Field": "Email",
146+
},
147+
Who: actual.Who,
148+
}}
149+
150+
s.EqualError(expected, actual.Error())
151+
}
152+
119153
func (s *CollectionTestSuite) TestDelete() {
120154
aggregate := user.RandomPrimitive()
121155

@@ -129,7 +163,21 @@ func (s *CollectionTestSuite) TestDelete() {
129163

130164
_, err := s.sut.Search(criteria)
131165

132-
s.Error(err)
166+
var actual *errors.NotExist
167+
168+
s.ErrorAs(err, &actual)
169+
170+
expected := &errors.NotExist{Bubble: &errors.Bubble{
171+
When: actual.When,
172+
Where: "HandleErrNotFound",
173+
What: fmt.Sprintf("%s not found", aggregate.ID.Value),
174+
Why: errors.Meta{
175+
"Index": aggregate.ID.Value,
176+
},
177+
Who: actual.Who,
178+
}}
179+
180+
s.EqualError(expected, actual.Error())
133181
}
134182

135183
func (s *CollectionTestSuite) TestSearch() {
@@ -148,7 +196,7 @@ func (s *CollectionTestSuite) TestSearch() {
148196
s.Equal(expected, actual)
149197
}
150198

151-
func (s *CollectionTestSuite) TestSearchErrDocumentNotFound() {
199+
func (s *CollectionTestSuite) TestSearchErrNotFound() {
152200
aggregate := user.RandomPrimitive()
153201

154202
criteria := &repository.SearchCriteria{
@@ -163,7 +211,7 @@ func (s *CollectionTestSuite) TestSearchErrDocumentNotFound() {
163211

164212
expected := &errors.NotExist{Bubble: &errors.Bubble{
165213
When: actual.When,
166-
Where: "HandleDocumentNotFound",
214+
Where: "HandleErrNotFound",
167215
What: fmt.Sprintf("%s not found", aggregate.ID.Value),
168216
Why: errors.Meta{
169217
"Index": aggregate.ID.Value,

pkg/context/user/infrastructure/persistence/sqlite/table/table_test.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@ import (
55
"os"
66
"testing"
77

8+
"github.com/stretchr/testify/suite"
9+
810
"github.com/bastean/codexgo/v4/pkg/context/shared/domain/errors"
911
"github.com/bastean/codexgo/v4/pkg/context/shared/infrastructure/persistences/sqlite"
1012
"github.com/bastean/codexgo/v4/pkg/context/user/domain/aggregate/user"
1113
"github.com/bastean/codexgo/v4/pkg/context/user/domain/repository"
1214
"github.com/bastean/codexgo/v4/pkg/context/user/infrastructure/persistence/sqlite/table"
13-
"github.com/stretchr/testify/suite"
1415
)
1516

1617
type TableTestSuite struct {
@@ -161,7 +162,21 @@ func (s *TableTestSuite) TestDelete() {
161162

162163
_, err := s.sut.Search(criteria)
163164

164-
s.Error(err)
165+
var actual *errors.NotExist
166+
167+
s.ErrorAs(err, &actual)
168+
169+
expected := &errors.NotExist{Bubble: &errors.Bubble{
170+
When: actual.When,
171+
Where: "HandleErrNotFound",
172+
What: fmt.Sprintf("%s not found", aggregate.ID.Value),
173+
Why: errors.Meta{
174+
"Index": aggregate.ID.Value,
175+
},
176+
Who: actual.Who,
177+
}}
178+
179+
s.EqualError(expected, actual.Error())
165180
}
166181

167182
func (s *TableTestSuite) TestSearch() {

0 commit comments

Comments
 (0)