-
Notifications
You must be signed in to change notification settings - Fork 573
Description
Is your feature request related to a problem? Please describe.
In the AWS documentation, the handler for the function is shown to have the following signature
- func ()
- func () error
- func (TIn) error
- func () (TOut, error)
- func (TIn) (TOut, error)
- func (context.Context) error
- func (context.Context, TIn) error
- func (context.Context) (TOut, error)
- func (context.Context, TIn) (TOut, error)
https://docs.aws.amazon.com/lambda/latest/dg/golang-handler.html
But it also says the following.
The handler may take between 0 and 2 arguments. If there are two arguments, the first argument must implement context.Context.
The first argument in the signature of the function that takes two arguments is clearly context.Context, but the panic occurs when customContext is taken as an argument.
For example, deploy and execute the following code to AWS Lambda.
package main
import (
"context"
"log"
"github.com/aws/aws-lambda-go/lambda"
)
func main() {
lambda.Start(Handle)
}
func Handle(ctx customContext) {
log.Println("hello")
return
}
// customContext satisfies "context.Context"
type customContext struct {
context.Context
}When this Lambda is executed, a panic occurs as shown below.
reflect: Call using *context.valueCtx as type main.customContext: string
[
{
"path": "github.com/aws/aws-lambda-go@v1.24.0/lambda/errors.go",
"line": 39,
"label": "lambdaPanicResponse"
},
{
"path": "github.com/aws/aws-lambda-go@v1.24.0/lambda/function.go",
"line": 36,
"label": "(*Function).Invoke.func1"
},
{
"path": "runtime/panic.go",
"line": 965,
"label": "gopanic"
},
{
"path": "reflect/value.go",
"line": 406,
"label": "Value.call"
},
{
"path": "reflect/value.go",
"line": 337,
"label": "Value.Call"
},
{
"path": "github.com/aws/aws-lambda-go@v1.24.0/lambda/handler.go",
"line": 124,
"label": "NewHandler.func1"
},
{
"path": "github.com/aws/aws-lambda-go@v1.24.0/lambda/handler.go",
"line": 24,
"label": "lambdaHandler.Invoke"
},
{
"path": "github.com/aws/aws-lambda-go@v1.24.0/lambda/function.go",
"line": 64,
"label": "(*Function).Invoke"
},
{
"path": "reflect/value.go",
"line": 476,
"label": "Value.call"
},
{
"path": "reflect/value.go",
"line": 337,
"label": "Value.Call"
},
{
"path": "net/rpc/server.go",
"line": 377,
"label": "(*service).call"
},
{
"path": "runtime/asm_amd64.s",
"line": 1371,
"label": "goexit"
}
]
Describe the solution you'd like
If we take context.Context as an argument, we need to make sure that the first argument of the function signature is context.Context explicitly.
aws-lambda-go/lambda/handler.go
Lines 48 to 50 in 5d64132
| contextType := reflect.TypeOf((*context.Context)(nil)).Elem() | |
| argumentType := handler.In(0) | |
| handlerTakesContext = argumentType.Implements(contextType) |
The above implementation only checks if the argument satisfies context.Context, so if a custom context that satisfies context.Context is the first argument, it cannot be checked by the above validation.
Describe alternatives you've considered
I wasn't sure if it was correct to explicitly accept only context.Context as a signature, or if we will accept a custom context satisfying context.Context as a function signature.
Additional context
Nothing.