Skip to content

Commit 74fe4a6

Browse files
author
enikon
authored
OAS-10870 go driver conflict error should expose the name of a field that violates a unique constraint #593 (#680)
1 parent 9993f28 commit 74fe4a6

File tree

4 files changed

+35
-8
lines changed

4 files changed

+35
-8
lines changed

v2/arangodb/collection_documents_create.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,20 +49,22 @@ type CollectionDocumentCreate interface {
4949

5050
// CreateDocuments creates multiple documents in the collection.
5151
// The document data is loaded from the given documents slice, the documents metadata is returned.
52-
// If a documents element already contains a `_key` field, this will be used as key of the new document,
52+
// If a document element already contains a `_key` field, this will be used as key of the new document,
5353
// otherwise a unique key is created.
54-
// If a documents element contains a `_key` field with a duplicate key, other any other field violates an index constraint,
55-
// a ConflictError is returned in its indeed in the errors slice.
54+
// If a document element contains a `_key` field with a duplicate key, or any other field that violates an index constraint,
55+
// then the ConflictError for a specific document will be returned only while reading from CollectionDocumentCreateResponseReader
56+
// and not as the error output of this function.
5657
// If the create request itself fails or one of the arguments is invalid, an error is returned.
5758
// SmartGraphs and EnterpriseGraphs cannot use existing collections and cannot use the document interface
5859
CreateDocuments(ctx context.Context, documents interface{}) (CollectionDocumentCreateResponseReader, error)
5960

6061
// CreateDocumentsWithOptions creates multiple documents in the collection.
6162
// The document data is loaded from the given documents slice, the documents metadata is returned.
62-
// If a documents element already contains a `_key` field, this will be used as key of the new document,
63+
// If a document element already contains a `_key` field, this will be used as key of the new document,
6364
// otherwise a unique key is created.
64-
// If a documents element contains a `_key` field with a duplicate key, other any other field violates an index constraint,
65-
// a ConflictError is returned in its indeed in the errors slice.
65+
// If a document element contains a `_key` field with a duplicate key, or any other field that violates an index constraint,
66+
// then the ConflictError for a specific document will be returned only while reading from CollectionDocumentCreateResponseReader
67+
// and not as the error output of this function.
6668
// If the create request itself fails or one of the arguments is invalid, an error is returned.
6769
// SmartGraphs and EnterpriseGraphs cannot use existing collections and cannot use the document interface
6870
CreateDocumentsWithOptions(ctx context.Context, documents interface{}, opts *CollectionDocumentCreateOptions) (CollectionDocumentCreateResponseReader, error)

v2/arangodb/shared/error.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// DISCLAIMER
33
//
4-
// Copyright 2017-2024 ArangoDB GmbH, Cologne, Germany
4+
// Copyright 2017-2025 ArangoDB GmbH, Cologne, Germany
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@ import (
2626
"fmt"
2727
"io"
2828
"net/http"
29+
"regexp"
2930
)
3031

3132
const (
@@ -423,6 +424,23 @@ func (ae ArangoError) Temporary() bool {
423424
return ae.HasError && ae.Code == http.StatusServiceUnavailable
424425
}
425426

427+
// GetConflictKey if error was caused by Conflict it returns the key that caused it or "" otherwise
428+
func (ae ArangoError) GetConflictKey() string {
429+
if IsConflict(error(ae)) {
430+
// Whitespace symbols are not allowed as part of a key so trimming them will not result in a mistake.
431+
re := regexp.MustCompile(`conflicting key:\s*(.+)$`)
432+
match := re.FindStringSubmatch(ae.ErrorMessage)
433+
if len(match) == 1 {
434+
return match[1]
435+
} else {
436+
return ""
437+
}
438+
439+
} else {
440+
return ""
441+
}
442+
}
443+
426444
// newArangoError creates a new ArangoError with given values.
427445
func newArangoError(code, errorNum int, errorMessage string) error {
428446
return ArangoError{

v2/arangodb/shared/response.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ func (r ResponseStruct) AsArangoError() ArangoError {
100100
a.ErrorMessage = *r.ErrorMessage
101101
}
102102

103+
if r.ErrorMessage != nil {
104+
a.ErrorMessage = *r.ErrorMessage
105+
}
106+
103107
return a
104108
}
105109

v2/tests/database_collection_doc_create_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// DISCLAIMER
33
//
4-
// Copyright 2023-2024 ArangoDB GmbH, Cologne, Germany
4+
// Copyright 2023-2025 ArangoDB GmbH, Cologne, Germany
55
//
66
// Licensed under the Apache License, Version 2.0 (the "License");
77
// you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@ import (
2424
"context"
2525
"testing"
2626

27+
"github.com/arangodb/go-driver/v2/arangodb/shared"
2728
"github.com/arangodb/go-driver/v2/utils"
2829

2930
"github.com/stretchr/testify/require"
@@ -77,6 +78,8 @@ func Test_DatabaseCollectionDocCreateOverwrite(t *testing.T) {
7778
OverwriteMode: overwriteMode.New(),
7879
})
7980
require.Error(t, err)
81+
82+
require.Equal(t, meta.Key, err.(shared.ArangoError).GetConflictKey())
8083
require.Empty(t, metaConflict.Rev)
8184
require.Empty(t, metaConflict.Old)
8285
require.Empty(t, metaConflict.New)

0 commit comments

Comments
 (0)