kkHAIKE / contextcheck

Analyzer: check whether a function uses a non-inherited context
Apache License 2.0
43 stars 3 forks source link

False Positive on a Lambda function that takes a Mongo SessionContext #24

Open blainenelson opened 5 months ago

blainenelson commented 5 months ago

In the following function

func (d *storage) WithTransaction(
    ctx context.Context,
    fn func(context.Context) error,
) error {
    sess, err := d.client.StartSession()
    if err != nil {
        return err
    }
    defer sess.EndSession(ctx)

    _, err = sess.WithTransaction(
        ctx,
        func(sessCtx mongo.SessionContext) (interface{}, error) {
            return nil, fn(sessCtx)
        },
    )
    return err
}

we are now seeing a False Positive

Function `WithTransaction$1` should pass the context parameter (contextcheck)
        func(sessCtx mongo.SessionContext) (interface{}, error) {

It appears there is an issue in creating a lambda function in this way, perhaps because the lambda function takes a mongo.SessionContext instead of a context.Context even though the former extends the latter: https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo#SessionContext

This issue appears to have arisen with the latest release.

kkHAIKE commented 5 months ago

The essence of this issue lies in the inability to recognize embedded situations like mongo.SessionContext at present. In the future, it will be necessary to consider adding additional context type configurations. For now, you can consider making the following modifications.

// nolint: contextcheck
func TransactionCall(ctx SessionContext, f func(ctx context.Context, sessctx SessionContext) (interface{}, error)) {
   return f(ctx.Context, ctx)
}

sess.WithTransaction(
  ctx,
  func(sessCtx mongo.SessionContext) (interface{}, error) {
    return TransactionCall(sessCtx, fn)
  },
)