Skip to content

Commit

Permalink
update pkgs and go ver 1.19 (GO-5367) (#11)
Browse files Browse the repository at this point in the history
* update pkgs and go ver 1.19 (GO-5367)

* revert test name to original

* add standard sainsburys stuff

* add nl to end of file
  • Loading branch information
jfallis authored Sep 19, 2022
1 parent e2d63e5 commit a73f5c2
Show file tree
Hide file tree
Showing 10 changed files with 271 additions and 51 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
coverage.out
.idea
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
language: go

go:
- "1.13"
- "1.19"

before_install:
- go get -u -v github.com/axw/gocov/gocov
Expand Down
6 changes: 6 additions & 0 deletions ACCESSIBILITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Accessibility

This is a purely backend system that does not have any parts visible to Customers or Colleagues.
It does not have any interface that would require accessibility testing.

[See our Confluence page for more details](https://sainsburys-confluence.valiantys.net/display/GF/Accessibility+testing)
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# g8

Provides the following utilities to simplify working with AWS lambda and Api Gateway.
Provides the following utilities to simplify working with AWS lambda and API Gateway.

* Simple handler interface
* HTTP request parsing with JSON support and request body validation
Expand Down Expand Up @@ -128,7 +128,7 @@ handler := func(c *g8.APIGatewayProxyContext) error {
}
```

Writes the the following response, with status code 400
Writes the following response, with status code 400

```json
{
Expand All @@ -139,8 +139,13 @@ Writes the the following response, with status code 400

### Logging stack traces

Unhandled errors are logged automatically with a stack trace if the error is wrapped by [eris](https://github.com/rotisserie/eris).
Unhandled errors are logged automatically with a stack trace if the error is wrapped by [eris](https://github.com/rotisserie/eris).

The new version of eris handles errors differently and produce a different JSON response compared to the previous version, additionally all errors now produce a JSON response, please fully test these changes.

```go
eris.Wrapf(err, "failed to send offers to user id: %v", userID)
```

### Requirements
* Go 1.19+
3 changes: 2 additions & 1 deletion apigw_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,8 @@ func TestAPIGatewayProxyHandler_UnhandledErrorResponse(t *testing.T) {
HeaderPresent("Correlation-Id").
End()

assert.Equal(t, "Unhandled error: some error", jsonPath("$.message", logBuf.Bytes()))
assert.Equal(t, "some error", jsonPath("$.error.external", logBuf.Bytes()))
assert.Equal(t, "Unhandled error", jsonPath("$.message", logBuf.Bytes()))
}

func TestAPIGatewayProxyHandler_GetCookie(t *testing.T) {
Expand Down
24 changes: 17 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
module github.com/JSainsburyPLC/g8

go 1.13
go 1.19

require (
github.com/PaesslerAG/jsonpath v0.1.1
github.com/aws/aws-lambda-go v1.13.3
github.com/aws/aws-lambda-go v1.34.1
github.com/gaw508/lambda-proxy-http-adapter v0.1.0
github.com/google/uuid v1.1.1
github.com/newrelic/go-agent v3.0.0+incompatible
github.com/rotisserie/eris v0.2.0
github.com/rs/zerolog v1.17.2
github.com/google/uuid v1.3.0
github.com/newrelic/go-agent v3.19.0+incompatible
github.com/rotisserie/eris v0.5.4
github.com/rs/zerolog v1.28.0
github.com/steinfletcher/apitest v1.4.0
github.com/stretchr/testify v1.5.1
github.com/stretchr/testify v1.7.2
)

require (
github.com/PaesslerAG/gval v1.0.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
57 changes: 31 additions & 26 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,46 +4,51 @@ github.com/PaesslerAG/gval v1.0.0/go.mod h1:y/nm5yEyTeX6av0OfKJNp9rBNj2XrGhAf5+v
github.com/PaesslerAG/jsonpath v0.1.0/go.mod h1:4BzmtoM/PI8fPO4aQGIusjGxGir2BzcV0grWtFzq1Y8=
github.com/PaesslerAG/jsonpath v0.1.1 h1:c1/AToHQMVsduPAa4Vh6xp2U0evy4t8SWp8imEsylIk=
github.com/PaesslerAG/jsonpath v0.1.1/go.mod h1:lVboNxFGal/VwW6d9JzIy56bUsYAP6tH/x80vjnCseY=
github.com/aws/aws-lambda-go v1.13.3 h1:SuCy7H3NLyp+1Mrfp+m80jcbi9KYWAs9/BXwppwRDzY=
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/aws/aws-lambda-go v1.34.1 h1:M3a/uFYBjii+tDcOJ0wL/WyFi2550FHoECdPf27zvOs=
github.com/aws/aws-lambda-go v1.34.1/go.mod h1:jwFe2KmMsHmffA1X2R09hH6lFzJQxzI8qK17ewzbQMM=
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gaw508/lambda-proxy-http-adapter v0.1.0 h1:0QDBKYl4OJZ5YlNdXXqNuMUjBRVqxWwApP4hbxdTfdA=
github.com/gaw508/lambda-proxy-http-adapter v0.1.0/go.mod h1:8lk+YsNGsT8W5tjyznIFP1Y+ZtL/4SxwUPBfQAknucQ=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/newrelic/go-agent v3.0.0+incompatible h1:OVbR4jHZfsqK50qz08yi2hxPvESVbZ7uhPbfihytcWE=
github.com/newrelic/go-agent v3.0.0+incompatible/go.mod h1:a8Fv1b/fYhFSReoTU6HDkTYIMZeSVNffmoS726Y0LzQ=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/newrelic/go-agent v3.19.0+incompatible h1:fuuC8lj6MW8AQEzTj09Wnto53ZobBeBkDBveC0iKfZw=
github.com/newrelic/go-agent v3.19.0+incompatible/go.mod h1:a8Fv1b/fYhFSReoTU6HDkTYIMZeSVNffmoS726Y0LzQ=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rotisserie/eris v0.2.0 h1:WRSj1amcCF98U04ur8Sj1oOKRRaFwvJ6i+z+97jfiXc=
github.com/rotisserie/eris v0.2.0/go.mod h1:DfmQXutjjasYYOYqyqgnevbDzsVLOwG/KWlwVkBoU3U=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/zerolog v1.17.2 h1:RMRHFw2+wF7LO0QqtELQwo8hqSmqISyCJeFeAAuWcRo=
github.com/rs/zerolog v1.17.2/go.mod h1:9nvC1axdVrAHcu/s9taAVfBuIdTZLVQmKQyvrUjF5+I=
github.com/rotisserie/eris v0.5.4 h1:Il6IvLdAapsMhvuOahHWiBnl1G++Q0/L5UIkI5mARSk=
github.com/rotisserie/eris v0.5.4/go.mod h1:Z/kgYTJiJtocxCbFfvRmO+QejApzG6zpyky9G1A4g9s=
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY=
github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/steinfletcher/apitest v1.4.0 h1:NfKf/kOTtzj/Y/T42570hNGlyVfS1lWPYTNAs6BonFw=
github.com/steinfletcher/apitest v1.4.0/go.mod h1:pCHKMM2TcH1pezw/xbmilaCdK9/dGsoCZBafwaqJ2sY=
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41 h1:ohgcoMbSofXygzo6AD2I1kz3BFmW1QArPYTtwEM3UXc=
golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
14 changes: 5 additions & 9 deletions handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,9 @@ func configureLogger(conf HandlerConfig) zerolog.Context {
}

func logUnhandledError(logger zerolog.Logger, err error) {
if isErisErr := eris.Unpack(err).ExternalErr == ""; isErisErr {
logger.Error().
Fields(map[string]interface{}{
"error": eris.ToJSON(err, true),
}).
Msg("Unhandled error")
} else {
logger.Error().Msgf("Unhandled error: %+v", err)
}
logger.Error().
Fields(map[string]interface{}{
"error": eris.ToJSON(err, true),
}).
Msg("Unhandled error")
}
125 changes: 121 additions & 4 deletions handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package g8_test
import (
"bytes"
"errors"
"fmt"
"net/http"
"testing"

Expand All @@ -29,7 +30,7 @@ func TestError_Error(t *testing.T) {

func TestAPIGatewayProxyHandler_UnhandledErrorResponseWithStackTrace(t *testing.T) {
h := func(c *g8.APIGatewayProxyContext) error {
return eris.Wrap(errors.New("library err"), "application err")
return eris.Wrap(errors.New("external error"), "additional context")
}

logBuf := &bytes.Buffer{}
Expand All @@ -50,8 +51,124 @@ func TestAPIGatewayProxyHandler_UnhandledErrorResponseWithStackTrace(t *testing.
End()

assert.Equal(t, "Unhandled error", jsonPath("$.message", logBuf.Bytes()))
assert.Equal(t, "library err", jsonPath("$.error.root.message", logBuf.Bytes()))
assert.Equal(t, "additional context", jsonPath("$.error.root.message", logBuf.Bytes()))
assert.Equal(t, "external error", jsonPath("$.error.external", logBuf.Bytes()))
assert.NotEmpty(t, jsonPath("$.error.root.stack", logBuf.Bytes()))
assert.Equal(t, "application err", jsonPath("$.error.wrap[0].message", logBuf.Bytes()))
assert.NotEmpty(t, jsonPath("$.error.wrap[0].stack", logBuf.Bytes()))
}

// TestAPIGatewayProxyHandler_UnhandledErrorsResponseWithStackTrace tests external errors to json
// https://github.com/rotisserie/eris/blob/a9462968dc6916f50e0c4e89c9d01faa642872f4/format_test.go#L191
func TestAPIGatewayProxyHandler_UnhandledErrorsResponseWithStackTrace(t *testing.T) {
stackRegex := "g8_test\\.TestAPIGatewayProxyHandler_UnhandledErrorsResponseWithStackTrace:.+:\\d+"
type rootErr struct {
message *string
stack []string
}
type wrapErr struct {
message string
stack string
}
type output struct {
root rootErr
wrap []wrapErr
externalMessage *string
message string
}

tests := map[string]struct {
input error
output
}{
"basic root error": {
input: eris.New("root error"),
// {"root":{"message":"root error"}}
output: output{
root: rootErr{
message: strToPtr("root error"),
stack: []string{stackRegex},
},
message: "Unhandled error",
},
},
"basic wrapped error": {
input: eris.Wrap(eris.Wrap(eris.New("root error"), "additional context"), "even more context"),
// {"root":{"message":"root error"},"wrap":[{"message":"even more context"},{"message":"additional context"}]}
output: output{
root: rootErr{
message: strToPtr("root error"),
stack: []string{stackRegex, stackRegex, stackRegex},
},
wrap: []wrapErr{
{
message: "even more context",
stack: stackRegex,
},
{
message: "additional context",
stack: stackRegex,
},
},
message: "Unhandled error",
},
},
"external error": {
input: eris.Wrap(errors.New("external error"), "additional context"),
// {"external":"external error","root":{"message":"additional context"}}
output: output{
externalMessage: strToPtr("external error"),
root: rootErr{
message: strToPtr("additional context"),
stack: []string{stackRegex},
},
message: "Unhandled error",
},
},
}
for desc, tt := range tests {
t.Run(desc, func(t *testing.T) {
h := func(c *g8.APIGatewayProxyContext) error {
return tt.input
}

logBuf := &bytes.Buffer{}
lh := g8.APIGatewayProxyHandler(h, g8.HandlerConfig{
Logger: zerolog.New(logBuf),
})

apitest.New().
Handler(adapter.GetHttpHandlerWithContext(lh, "/", nil)).
Get("/").
Expect(t).
Status(http.StatusInternalServerError).
Body(`{
"code": "INTERNAL_SERVER_ERROR",
"detail": "Internal server error"
}`).
HeaderPresent("Correlation-Id").
End()

// root
if tt.root.message != nil {
assert.Equal(t, *tt.root.message, jsonPath("$.error.root.message", logBuf.Bytes()))
}
for x, stack := range tt.root.stack {
assert.Regexp(t, stack, jsonPath(fmt.Sprintf("$.error.root.stack[%d]", x), logBuf.Bytes()))
}

// wrap
for x, stack := range tt.wrap {
assert.Equal(t, stack.message, jsonPath(fmt.Sprintf("$.error.wrap[%d].message", x), logBuf.Bytes()))
assert.Regexp(t, stack.stack, jsonPath(fmt.Sprintf("$.error.wrap[%d].stack", x), logBuf.Bytes()))
}

// external
if tt.externalMessage != nil {
assert.Equal(t, *tt.externalMessage, jsonPath("$.error.external", logBuf.Bytes()))
}
})
}
}

func strToPtr(v string) *string {
return &v
}
Loading

0 comments on commit a73f5c2

Please sign in to comment.