in lambda/invoke_loop.go [46:102]
func handleInvoke(invoke *invoke, handler *handlerOptions) error {
// set the deadline
deadline, err := parseDeadline(invoke)
if err != nil {
return reportFailure(invoke, lambdaErrorResponse(err))
}
ctx, cancel := context.WithDeadline(handler.baseContext, deadline)
defer cancel()
// set the invoke metadata values
lc := lambdacontext.LambdaContext{
AwsRequestID: invoke.id,
InvokedFunctionArn: invoke.headers.Get(headerInvokedFunctionARN),
}
if err := parseClientContext(invoke, &lc.ClientContext); err != nil {
return reportFailure(invoke, lambdaErrorResponse(err))
}
if err := parseCognitoIdentity(invoke, &lc.Identity); err != nil {
return reportFailure(invoke, lambdaErrorResponse(err))
}
ctx = lambdacontext.NewContext(ctx, &lc)
// set the trace id
traceID := invoke.headers.Get(headerTraceID)
os.Setenv("_X_AMZN_TRACE_ID", traceID)
// nolint:staticcheck
ctx = context.WithValue(ctx, "x-amzn-trace-id", traceID)
// call the handler, marshal any returned error
response, invokeErr := callBytesHandlerFunc(ctx, invoke.payload, handler.handlerFunc)
if invokeErr != nil {
if err := reportFailure(invoke, invokeErr); err != nil {
return err
}
if invokeErr.ShouldExit {
return fmt.Errorf("calling the handler function resulted in a panic, the process should exit")
}
return nil
}
// if the response needs to be closed (ex: net.Conn, os.File), ensure it's closed before the next invoke to prevent a resource leak
if response, ok := response.(io.Closer); ok {
defer response.Close()
}
// if the response defines a content-type, plumb it through
contentType := contentTypeBytes
type ContentType interface{ ContentType() string }
if response, ok := response.(ContentType); ok {
contentType = response.ContentType()
}
if err := invoke.success(response, contentType); err != nil {
return fmt.Errorf("unexpected error occurred when sending the function functionResponse to the API: %v", err)
}
return nil
}