Skip to content

Commit

Permalink
lambda: check if error type is InvokeResponse_Error (#312)
Browse files Browse the repository at this point in the history
Currently, we cannot set the errorType field without creating a custom
named error type. This causes a proliferation of dummy named error types
whose only purpose is to set a text field, and limits the errorType
field to what can be expressed as an identifier.

This change checks that the panicked or returned error is if type
InvokeResponse_Error, and if so, uses it directly in the invoker's
response. InvokeResponse_Error is now updated to implement error.

Note: This is fully backwards compatible, since InvokeResponse_Error
previously did not implement the error interface.

Fixes #308.

Co-authored-by: Bryan Moffatt <bmoffatt@users.noreply.github.com>
  • Loading branch information
smasher164 and bmoffatt committed Sep 22, 2020
1 parent 4145757 commit c6b2e41
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 0 deletions.
6 changes: 6 additions & 0 deletions lambda/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ func getErrorType(err interface{}) string {
}

func lambdaErrorResponse(invokeError error) *messages.InvokeResponse_Error {
if ive, ok := invokeError.(messages.InvokeResponse_Error); ok {
return &ive
}
var errorName string
if errorType := reflect.TypeOf(invokeError); errorType.Kind() == reflect.Ptr {
errorName = errorType.Elem().Name()
Expand All @@ -30,6 +33,9 @@ func lambdaErrorResponse(invokeError error) *messages.InvokeResponse_Error {
}

func lambdaPanicResponse(err interface{}) *messages.InvokeResponse_Error {
if ive, ok := err.(messages.InvokeResponse_Error); ok {
return &ive
}
panicInfo := getPanicInfo(err)
return &messages.InvokeResponse_Error{
Message: panicInfo.Message,
Expand Down
8 changes: 8 additions & 0 deletions lambda/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"testing"

"github.com/aws/aws-lambda-go/lambda/handlertrace"
"github.com/aws/aws-lambda-go/lambda/messages"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -187,6 +188,13 @@ func TestInvokes(t *testing.T) {
return struct{ Number int }{event}, nil
},
},
{
input: `"Lambda"`,
expected: expected{"", messages.InvokeResponse_Error{Message: "message", Type: "type"}},
handler: func(e interface{}) (interface{}, error) {
return nil, messages.InvokeResponse_Error{Message: "message", Type: "type"}
},
},
}
for i, testCase := range testCases {
testCase := testCase
Expand Down
6 changes: 6 additions & 0 deletions lambda/messages/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

package messages

import "fmt"

type PingRequest struct {
}

Expand Down Expand Up @@ -36,6 +38,10 @@ type InvokeResponse_Error struct {
ShouldExit bool `json:"-"`
}

func (e InvokeResponse_Error) Error() string {
return fmt.Sprintf("%#v", e)
}

type InvokeResponse_Error_StackFrame struct {
Path string `json:"path"`
Line int32 `json:"line"`
Expand Down
6 changes: 6 additions & 0 deletions lambda/panic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"strings"
"testing"

"github.com/aws/aws-lambda-go/lambda/messages"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -37,6 +38,11 @@ func TestPanicFormattingCustomError(t *testing.T) {
assertPanicMessage(t, func() { panic(customError) }, customError.Error())
}

func TestPanicFormattingInvokeResponse_Error(t *testing.T) {
ive := &messages.InvokeResponse_Error{Message: "message", Type: "type"}
assertPanicMessage(t, func() { panic(ive) }, ive.Error())
}

func TestFormatFrame(t *testing.T) {
var tests = []struct {
inputPath string
Expand Down

0 comments on commit c6b2e41

Please sign in to comment.