From 488ab7a1ab31f7ada84a0fca1c6e36a27c81e77a Mon Sep 17 00:00:00 2001 From: smasher164 Date: Tue, 11 Aug 2020 19:32:23 -0400 Subject: [PATCH] lambda: check if error type is InvokeResponse_Error 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. --- lambda/errors.go | 6 ++++++ lambda/handler_test.go | 8 ++++++++ lambda/messages/messages.go | 6 ++++++ lambda/panic_test.go | 6 ++++++ 4 files changed, 26 insertions(+) diff --git a/lambda/errors.go b/lambda/errors.go index 619f976c..5d482d04 100644 --- a/lambda/errors.go +++ b/lambda/errors.go @@ -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() @@ -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, diff --git a/lambda/handler_test.go b/lambda/handler_test.go index b76e73e8..476dc18a 100644 --- a/lambda/handler_test.go +++ b/lambda/handler_test.go @@ -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" ) @@ -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 diff --git a/lambda/messages/messages.go b/lambda/messages/messages.go index 7f7f1093..9f8b3575 100644 --- a/lambda/messages/messages.go +++ b/lambda/messages/messages.go @@ -2,6 +2,8 @@ package messages +import "fmt" + type PingRequest struct { } @@ -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"` diff --git a/lambda/panic_test.go b/lambda/panic_test.go index 92db8fd7..b2135ecd 100644 --- a/lambda/panic_test.go +++ b/lambda/panic_test.go @@ -6,6 +6,7 @@ import ( "strings" "testing" + "github.com/aws/aws-lambda-go/lambda/messages" "github.com/stretchr/testify/assert" ) @@ -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