[GODRIVER-3048] HasErrorCode() should parse MultipleErrorsOccurred’s `errInfo`. Created: 10/Nov/23  Updated: 06/Feb/24

Status: Blocked
Project: Go Driver
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major - P3
Reporter: Felipe Gasper Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Depends
depends on DRIVERS-2775 Investigate optionally supporting par... Needs Triage
is depended on by GODRIVER-3086 Add a method to ServerError that retu... Blocked
Related
related to GODRIVER-3086 Add a method to ServerError that retu... Blocked
Quarter: FY24Q1
Documentation Changes Summary:

1. What would you like to communicate to the user about this feature?
2. Would you like the user to see examples of the syntax and/or executable code and its output?
3. Which versions of the driver/connector does this apply to?


 Description   

Detailed steps to reproduce the problem?

  1. Create a 2-shard cluster.
  2. Create a collection with 1 chunk on either cluster.
  3. Create failpoints on both clusters for the “update” command. Give either failpoint a different error code (e.g., 1 and 2).
  4. On the mongos, run updateMany({},
    Unknown macro: { $set}

    ). The command will receive a MultipleErrorsOccurred value (code=65).

  5. In Go, HasErrorCode(2) on that error should return true if any of the component errors has error code 2.

The error structure is:

{
  index: 0,
  code: 65,
  errInfo: {
    causedBy: [
      {
        index: 0,
        code: 1,
        errmsg: "Failing command via 'failCommand' failpoint"
      },
      {
        index: 0,
        code: 2,
        errmsg: "Failing command via 'failCommand' failpoint"
      }
    ]
  },
  [Symbol(errorLabels)]: Set(0) {}
}

Example failpoint creation (note the `failInternalCommands` flag):

db.adminCommand({ configureFailPoint: "failCommand", mode: "alwaysOn", data: { errorCode:2, failCommands: ["update", 'find'], failInternalCommands:true} })

Definition of done: what must be done to consider the task complete?

HasErrorCode() should handle MultipleErrorsOccurred as it currently handles `WriteError`s.

The exact Go version used, with patch level:

1.20.11

The exact version of the Go driver used:

1.12.1

Describe how MongoDB is set up. Local vs Hosted, version, topology, load balanced, etc.

2-shard cluster; each shard has a single node.

The operating system and version (e.g. Windows 7, OSX 10.8, ...)

macOS

Security Vulnerabilities

n/a



 Comments   
Comment by Preston Vasquez [ 14/Nov/23 ]

felipe.gasper@mongodb.com Yes, I believe it is accurately documented. From the documentation

// HasErrorCode returns true if the error has the specified code. 

I would expect one of two error codes to indicate a MultipleErrorsOccured error: 65 or 40671. See here for the rationale on the latter. In these cases to get more information you can inspect the Raw value.

This is not a bug, as the driver's specifications explicitly state not to do this:

Drivers MUST NOT parse inside errInfo. 

The argument for why can be found here:

I think it would be even riskier to attempt to parse errInfo and construct a helpful error message – both due to implementation complexity and needing to rely on a stable response format. Presumably there was a reason the server team did not choose to do so for SERVER-20547; however, the scope/design documents linked from DRIVERS-820 do not explain why. There is some mention of truncating errInfo to a generic string ("could not provide detailed error information as the error grew too large") if the detailed document would exceed some size limit.

I've created DRIVERS-2775 to argue loosening this condition to allow us to implement this improvement. Thank you for bringing this to our attention

Comment by Felipe Gasper [ 14/Nov/23 ]

preston.vasquez@mongodb.com We could work around this by manually inspecting the response, yes.

But in that case, is HasErrorCode() accurately named and documented, if it only indicates the presence of an error code depending on how the server sent that error code?

Comment by Preston Vasquez [ 13/Nov/23 ]

felipe.gasper@mongodb.com Would you mind expanding on the use case of this and what the current behavior is? I think the server specifically sends error code 65 which comes with the extra information encapsulated in MultipleErrorsOccurredInfo. Can the mongosync team use the "Raw" value on the command error to get this extra info? From the comment on that extra info type:

[Info] contains the details for each [error] type.

 

	
fmt.Println("raw: ", err.(mongo.CommandError).Raw) // Check for extra info

Generated at Thu Feb 08 08:39:57 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.