From 1670ebd757501927fd7b97b6263b9fd7dfaad80f Mon Sep 17 00:00:00 2001 From: Evgeny Abramovich Date: Sun, 20 Nov 2022 12:46:53 -0400 Subject: [PATCH] Added panic interceptor --- .github/workflows/go.yml | 4 +-- .goreleaser.yaml | 1 + go.sum | 12 ------- internal/infrastructure/panic.go | 9 +++++ internal/infrastructure/panic_debug.go | 7 ++++ internal/infrastructure/panic_test.go | 50 ++++++++++++++++++++++++++ main.go | 18 ++++++---- 7 files changed, 81 insertions(+), 20 deletions(-) create mode 100644 internal/infrastructure/panic.go create mode 100644 internal/infrastructure/panic_debug.go create mode 100644 internal/infrastructure/panic_test.go diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 0450ce27..d2b34269 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -28,10 +28,10 @@ jobs: version: v1.50.1 - name: Build - run: go build -v . + run: go build -tags release -v . - name: Test - run: go test -json -v -coverprofile=coverage.out ./... > test-report.out + run: go test -tags release -json -v -coverprofile=coverage.out ./... > test-report.out - name: SonarCloud Scan uses: SonarSource/sonarcloud-github-action@master diff --git a/.goreleaser.yaml b/.goreleaser.yaml index b737fca2..84fcc63f 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -20,6 +20,7 @@ builds: main: '.' ldflags: - -s -w -X main.Version={{ .Version }} + tags: [release] archives: - replacements: darwin: MacOS diff --git a/go.sum b/go.sum index e67eb561..0ebfb71c 100644 --- a/go.sum +++ b/go.sum @@ -196,8 +196,6 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg= -github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -225,8 +223,6 @@ github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkG github.com/pterm/pterm v0.12.49 h1:qeNm0wTWawy6WhKoY8ZKq6qTXFr0s2UtUyRW0yVztEg= github.com/pterm/pterm v0.12.49/go.mod h1:D4OBoWNqAfXkm5QLTjIgjNiMXPHemLJHnIreGUsWzWg= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8= -github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw= github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -234,8 +230,6 @@ github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBO github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw= -github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk= github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= @@ -353,8 +347,6 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20221014081412-f15817d10f9b h1:tvrvnPFcdzp294diPnrdZZZ8XUt2Tyj7svb7X52iDuU= -golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -419,16 +411,12 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20221006211917-84dc82d7e875 h1:AzgQNqF+FKwyQ5LbVrVqOcuuFB67N47F9+htZYH0wFM= -golang.org/x/sys v0.0.0-20221006211917-84dc82d7e875/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.0.0-20220919170432-7a66f970e087 h1:tPwmk4vmvVCMdr98VgL4JH+qZxPL8fqlUOHnyOM8N3w= -golang.org/x/term v0.0.0-20220919170432-7a66f970e087/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0 h1:z85xZCsEl7bi/KwbNADeBYoOP0++7W1ipu+aGnpwzRM= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/internal/infrastructure/panic.go b/internal/infrastructure/panic.go new file mode 100644 index 00000000..2b97ad70 --- /dev/null +++ b/internal/infrastructure/panic.go @@ -0,0 +1,9 @@ +//go:build release + +package infrastructure + +func PanicInterceptor(action func(interface{})) { + if recovered := recover(); recovered != nil { + action(recovered) + } +} diff --git a/internal/infrastructure/panic_debug.go b/internal/infrastructure/panic_debug.go new file mode 100644 index 00000000..73558c46 --- /dev/null +++ b/internal/infrastructure/panic_debug.go @@ -0,0 +1,7 @@ +//go:build !release + +package infrastructure + +func PanicInterceptor(action func(interface{})) { + // stub method +} diff --git a/internal/infrastructure/panic_test.go b/internal/infrastructure/panic_test.go new file mode 100644 index 00000000..c9c7ce12 --- /dev/null +++ b/internal/infrastructure/panic_test.go @@ -0,0 +1,50 @@ +//go:build release + +package infrastructure + +import ( + "errors" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestPanicInterceptor(t *testing.T) { + tests := []struct { + name string + panicData interface{} + shouldBeCalled bool + }{ + { + name: "intercepts panic and return with exit code 3", + panicData: "test panic", + shouldBeCalled: true, + }, + { + name: "intercepts panic and return with exit code 0", + panicData: errors.New("test error"), + shouldBeCalled: true, + }, + { + name: "intercepts panic and return with exit code 0", + panicData: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + called := false + + assert.NotPanics(t, func() { + defer PanicInterceptor(func(data interface{}) { + called = true + assert.Equal(t, tt.panicData, data) + }) + + panic(tt.panicData) + }) + + assert.Equal(t, tt.shouldBeCalled, called) + }) + } +} diff --git a/main.go b/main.go index 2a8b63c3..ad1f5621 100644 --- a/main.go +++ b/main.go @@ -15,6 +15,7 @@ import ( "github.com/evg4b/uncors/internal/ui" "github.com/evg4b/uncors/internal/urlreplacer" "github.com/pseidemann/finish" + "github.com/pterm/pterm" "github.com/spf13/pflag" "github.com/spf13/viper" "gopkg.in/yaml.v3" @@ -39,6 +40,11 @@ func main() { pflag.String("mocks", "", "File with configured mocks") pflag.Bool("debug", false, "Show debug output") + defer infrastructure.PanicInterceptor(func(value interface{}) { + pterm.Error.Println(value) + os.Exit(1) + }) + pflag.Usage = func() { ui.Logo(Version) fmt.Fprintf(os.Stdout, "Usage of %s:\n", os.Args[0]) @@ -47,7 +53,7 @@ func main() { pflag.Parse() if err := viper.BindPFlags(pflag.CommandLine); err != nil { - log.Fatal(err) + panic(err) } httpPort := viper.GetInt("http-port") @@ -66,13 +72,13 @@ func main() { if len(mocksFile) > 0 { file, err := os.Open(mocksFile) if err != nil { - log.Fatal(err) + panic(err) } log.Debugf("Loaded file with mocks '%s'", mocksFile) decoder := yaml.NewDecoder(file) if err = decoder.Decode(&mocksDefs); err != nil { - log.Fatal(err) + panic(err) } } @@ -87,17 +93,17 @@ func main() { len(certFile) > 0 && len(keyFile) > 0, ) if err != nil { - log.Fatal(err) + panic(err) } factory, err := urlreplacer.NewURLReplacerFactory(mappings) if err != nil { - log.Fatal(err) + panic(err) } httpClient, err := infrastructure.MakeHTTPClient(viper.GetString("proxy")) if err != nil { - log.Fatal(err) + panic(err) } proxyMiddleware := proxy.NewProxyMiddleware(