Skip to content

Commit 264fbf6

Browse files
GODRIVER-3690 Extend CommandFailedEvent with error codes
1 parent 9bd07db commit 264fbf6

File tree

5 files changed

+58
-6
lines changed

5 files changed

+58
-6
lines changed

event/monitoring.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ type CommandSucceededEvent struct {
5454
type CommandFailedEvent struct {
5555
CommandFinishedEvent
5656
Failure error
57+
Codes []int32
5758
}
5859

5960
// CommandMonitor represents a monitor that is triggered for different events.

internal/integration/clam_prose_test.go

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ import (
1414

1515
"go.mongodb.org/mongo-driver/v2/bson"
1616
"go.mongodb.org/mongo-driver/v2/internal/assert"
17+
"go.mongodb.org/mongo-driver/v2/internal/failpoint"
1718
"go.mongodb.org/mongo-driver/v2/internal/integration/mtest"
1819
"go.mongodb.org/mongo-driver/v2/internal/integtest"
1920
"go.mongodb.org/mongo-driver/v2/internal/logger"
21+
"go.mongodb.org/mongo-driver/v2/internal/require"
2022
"go.mongodb.org/mongo-driver/v2/mongo"
2123
"go.mongodb.org/mongo-driver/v2/mongo/options"
2224
)
@@ -198,7 +200,6 @@ func clamMultiByteTruncLogs(mt *mtest.T) []truncValidator {
198200

199201
// Insert started.
200202
validators[0] = newTruncValidator(mt, cmd, func(cmd string) error {
201-
202203
// Remove the suffix from the command string.
203204
cmd = cmd[:len(cmd)-len(logger.TruncationSuffix)]
204205

@@ -396,3 +397,33 @@ func TestCommandLoggingAndMonitoringProse(t *testing.T) {
396397
})
397398
}
398399
}
400+
401+
func TestCommandFailedEvent_Codes(t *testing.T) {
402+
clientOpts := options.Client().SetRetryWrites(false)
403+
404+
mtOpts := mtest.NewOptions().MinServerVersion("8.0").ClientType(mtest.Pinned).ClientOptions(clientOpts)
405+
mt := mtest.New(t, mtOpts)
406+
407+
mt.Run("Top level code", func(mt *mtest.T) {
408+
mt.ResetClient(options.Client().SetRetryWrites(false))
409+
410+
mt.SetFailPoint(failpoint.FailPoint{
411+
ConfigureFailPoint: "failCommand",
412+
Mode: failpoint.Mode{
413+
Times: 1,
414+
},
415+
Data: failpoint.Data{
416+
FailCommands: []string{"insert"},
417+
ErrorCode: 1,
418+
},
419+
})
420+
421+
_, err := mt.Coll.InsertOne(context.Background(), bson.D{{"x", 1}})
422+
require.Error(mt, err, "expected InsertOne error, got nil")
423+
424+
failedEvent := mt.GetFailedEvent()
425+
426+
require.NotNil(mt, failedEvent, "expected CommandFailedEvent, got nil")
427+
require.Equal(mt, []int32{1}, failedEvent.Codes, "expected Codes to be [1], got %+v", failedEvent.Codes)
428+
})
429+
}

mongo/errors.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -364,10 +364,12 @@ func hasErrorCode(srvErr ServerError, code int) bool {
364364
return false
365365
}
366366

367-
var _ ServerError = CommandError{}
368-
var _ ServerError = WriteError{}
369-
var _ ServerError = WriteException{}
370-
var _ ServerError = BulkWriteException{}
367+
var (
368+
_ ServerError = CommandError{}
369+
_ ServerError = WriteError{}
370+
_ ServerError = WriteException{}
371+
_ ServerError = BulkWriteException{}
372+
)
371373

372374
var _ error = ClientBulkWriteException{}
373375

x/mongo/driver/errors.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,3 +566,21 @@ func ExtractErrorFromServerResponse(doc bsoncore.Document) error {
566566

567567
return nil
568568
}
569+
570+
// errorCodes extracts error codes from a driver.Error representing an ok:0
571+
// command failure. Since ok:0 indicates the command failed before processing
572+
// any operations, only a single error code is returned. Returns nil if the
573+
// error is not a driver.Error (e.g., network errors, WriteCommandError for
574+
// ok:1 responses).
575+
//
576+
// This function may be updated in the future to extract multiple error codes in
577+
// an ok:1 scenario. In such cases, there can be multiple error codes via
578+
// WriteErrors which represent individual operation failures within the context
579+
// of a write command.
580+
func errorCodes(err error) []int32 {
581+
if driversErr, ok := err.(Error); ok {
582+
return []int32{driversErr.Code}
583+
}
584+
585+
return nil
586+
}

x/mongo/driver/operation.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,6 @@ func (op Operation) Execute(ctx context.Context) error {
747747
var moreToCome bool
748748
var startedInfo startedInformation
749749
*wm, moreToCome, startedInfo, err = op.createWireMessage(ctx, maxTimeMS, (*wm)[:0], desc, conn, requestID)
750-
751750
if err != nil {
752751
return err
753752
}
@@ -2231,6 +2230,7 @@ func (op Operation) publishFinishedEvent(ctx context.Context, info finishedInfor
22312230

22322231
failedEvent := &event.CommandFailedEvent{
22332232
Failure: info.cmdErr,
2233+
Codes: errorCodes(info.cmdErr),
22342234
CommandFinishedEvent: finished,
22352235
}
22362236
op.CommandMonitor.Failed(ctx, failedEvent)

0 commit comments

Comments
 (0)