Skip to content

Commit 1503ae0

Browse files
authored
Merge pull request #36 from hellofresh/feature/wrap-errors
PT-6767 Return wrapped errors instead of logging
2 parents ec95d55 + eb378f9 commit 1503ae0

14 files changed

+150
-172
lines changed

README.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ import (
2525
"net/http"
2626
"time"
2727

28-
"github.com/hellofresh/health-go"
29-
healthMysql "github.com/hellofresh/health-go/checks/mysql"
28+
"github.com/hellofresh/health-go/v3"
29+
healthMysql "github.com/hellofresh/health-go/v3/checks/mysql"
3030
)
3131

3232
func main() {
@@ -69,8 +69,8 @@ import (
6969
"time"
7070

7171
"github.com/go-chi/chi"
72-
"github.com/hellofresh/health-go"
73-
healthMysql "github.com/hellofresh/health-go/checks/mysql"
72+
"github.com/hellofresh/health-go/v3"
73+
healthMysql "github.com/hellofresh/health-go/v3/checks/mysql"
7474
)
7575

7676
func main() {

_examples/server.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import (
55
"net/http"
66
"time"
77

8-
"github.com/hellofresh/health-go"
9-
healthHttp "github.com/hellofresh/health-go/checks/http"
10-
healthMySql "github.com/hellofresh/health-go/checks/mysql"
11-
healthPg "github.com/hellofresh/health-go/checks/postgres"
8+
"github.com/hellofresh/health-go/v3"
9+
healthHttp "github.com/hellofresh/health-go/v3/checks/http"
10+
healthMySql "github.com/hellofresh/health-go/v3/checks/mysql"
11+
healthPg "github.com/hellofresh/health-go/v3/checks/postgres"
1212
)
1313

1414
func main() {

checks/http/check.go

+8-14
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,36 @@ package http
22

33
import (
44
"context"
5-
"errors"
65
"net/http"
76
"time"
7+
8+
wErrors "github.com/pkg/errors"
89
)
910

11+
const defaultRequestTimeout = 5 * time.Second
12+
1013
// Config is the HTTP checker configuration settings container.
1114
type Config struct {
1215
// URL is the remote service health check URL.
1316
URL string
1417
// RequestTimeout is the duration that health check will try to consume published test message.
1518
// If not set - 5 seconds
1619
RequestTimeout time.Duration
17-
// LogFunc is the callback function for errors logging during check.
18-
// If not set logging is skipped.
19-
LogFunc func(err error, details string, extra ...interface{})
2020
}
2121

2222
// New creates new HTTP service health check that verifies the following:
2323
// - connection establishing
2424
// - getting response status from defined URL
2525
// - verifying that status code is less than 500
2626
func New(config Config) func() error {
27-
if config.LogFunc == nil {
28-
config.LogFunc = func(err error, details string, extra ...interface{}) {}
29-
}
30-
3127
if config.RequestTimeout == 0 {
32-
config.RequestTimeout = time.Second * 5
28+
config.RequestTimeout = defaultRequestTimeout
3329
}
3430

3531
return func() error {
3632
req, err := http.NewRequest(http.MethodGet, config.URL, nil)
3733
if err != nil {
38-
config.LogFunc(err, "Creating the request for the health check failed")
39-
return err
34+
return wErrors.Wrap(err, "creating the request for the health check failed")
4035
}
4136

4237
ctx, cancel := context.WithCancel(context.TODO())
@@ -51,13 +46,12 @@ func New(config Config) func() error {
5146

5247
res, err := http.DefaultClient.Do(req)
5348
if err != nil {
54-
config.LogFunc(err, "Making the request for the health check failed")
55-
return err
49+
return wErrors.Wrap(err, "making the request for the health check failed")
5650
}
5751
defer res.Body.Close()
5852

5953
if res.StatusCode >= http.StatusInternalServerError {
60-
return errors.New("remote service is not available at the moment")
54+
return wErrors.New("remote service is not available at the moment")
6155
}
6256

6357
return nil

checks/http/check_test.go

+9-9
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,6 @@ import (
99

1010
const httpURLEnv = "HEALTH_GO_HTTP_URL"
1111

12-
func getURL(t *testing.T) string {
13-
if httpURL, ok := os.LookupEnv(httpURLEnv); ok {
14-
return httpURL
15-
}
16-
17-
t.Fatalf("required env variable missing: %s", httpURLEnv)
18-
return ""
19-
}
20-
2112
func TestNew(t *testing.T) {
2213
check := New(Config{
2314
URL: getURL(t),
@@ -26,3 +17,12 @@ func TestNew(t *testing.T) {
2617
err := check()
2718
require.NoError(t, err)
2819
}
20+
21+
func getURL(t *testing.T) string {
22+
t.Helper()
23+
24+
httpURL, ok := os.LookupEnv(httpURLEnv)
25+
require.True(t, ok)
26+
27+
return httpURL
28+
}

checks/mongo/check.go

+15-19
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"time"
66

7+
wErrors "github.com/pkg/errors"
78
"go.mongodb.org/mongo-driver/mongo"
89
"go.mongodb.org/mongo-driver/mongo/options"
910
"go.mongodb.org/mongo-driver/mongo/readpref"
@@ -19,9 +20,6 @@ const (
1920
type Config struct {
2021
// DSN is the MongoDB instance connection DSN. Required.
2122
DSN string
22-
// LogFunc is the callback function for errors logging during check.
23-
// If not set logging is skipped.
24-
LogFunc func(err error, details string, extra ...interface{})
2523

2624
// TimeoutConnect defines timeout for establishing mongo connection, if not set - default value is used
2725
TimeoutConnect time.Duration
@@ -35,10 +33,6 @@ type Config struct {
3533
// - connection establishing
3634
// - doing the ping command
3735
func New(config Config) func() error {
38-
if config.LogFunc == nil {
39-
config.LogFunc = func(err error, details string, extra ...interface{}) {}
40-
}
41-
4236
if config.TimeoutConnect == 0 {
4337
config.TimeoutConnect = defaultTimeoutConnect
4438
}
@@ -51,42 +45,44 @@ func New(config Config) func() error {
5145
config.TimeoutPing = defaultTimeoutPing
5246
}
5347

54-
return func() error {
48+
return func() (checkErr error) {
5549
var ctx context.Context
5650
var cancel context.CancelFunc
5751

5852
client, err := mongo.NewClient(options.Client().ApplyURI(config.DSN))
5953
if err != nil {
60-
config.LogFunc(err, "MongoDB health check failed on client creation")
61-
return err
54+
checkErr = wErrors.Wrap(err, "mongoDB health check failed on client creation")
55+
return
6256
}
6357

6458
ctx, cancel = context.WithTimeout(context.Background(), config.TimeoutConnect)
6559
defer cancel()
66-
err = client.Connect(ctx)
6760

61+
err = client.Connect(ctx)
6862
if err != nil {
69-
config.LogFunc(err, "MongoDB health check failed on connect")
70-
return err
63+
checkErr = wErrors.Wrap(err, "mongoDB health check failed on connect")
64+
return
7165
}
7266

7367
defer func() {
7468
ctx, cancel = context.WithTimeout(context.Background(), config.TimeoutDisconnect)
7569
defer cancel()
76-
if err := client.Disconnect(ctx); err != nil {
77-
config.LogFunc(err, "MongoDB health check failed on closing connection")
70+
71+
// override checkErr only if there were no other errors
72+
if err := client.Disconnect(ctx); err != nil && checkErr == nil {
73+
checkErr = wErrors.Wrap(err, "mongoDB health check failed on closing connection")
7874
}
7975
}()
8076

8177
ctx, cancel = context.WithTimeout(context.Background(), config.TimeoutPing)
8278
defer cancel()
83-
err = client.Ping(ctx, readpref.Primary())
8479

80+
err = client.Ping(ctx, readpref.Primary())
8581
if err != nil {
86-
config.LogFunc(err, "MongoDB health check failed during ping")
87-
return err
82+
checkErr = wErrors.Wrap(err, "mongoDB health check failed on ping")
83+
return
8884
}
8985

90-
return nil
86+
return
9187
}
9288
}

checks/mongo/check_test.go

+9-9
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,6 @@ import (
99

1010
const mgDSNEnv = "HEALTH_GO_MG_DSN"
1111

12-
func getDSN(t *testing.T) string {
13-
if mongoDSN, ok := os.LookupEnv(mgDSNEnv); ok {
14-
return mongoDSN
15-
}
16-
17-
t.Fatalf("required env variable missing: %s", mgDSNEnv)
18-
return ""
19-
}
20-
2112
func TestNew(t *testing.T) {
2213
check := New(Config{
2314
DSN: getDSN(t),
@@ -26,3 +17,12 @@ func TestNew(t *testing.T) {
2617
err := check()
2718
require.NoError(t, err)
2819
}
20+
21+
func getDSN(t *testing.T) string {
22+
t.Helper()
23+
24+
mongoDSN, ok := os.LookupEnv(mgDSNEnv)
25+
require.True(t, ok)
26+
27+
return mongoDSN
28+
}

checks/mysql/check.go

+15-20
Original file line numberDiff line numberDiff line change
@@ -4,57 +4,52 @@ import (
44
"database/sql"
55

66
_ "github.com/go-sql-driver/mysql" // import mysql driver
7+
wErrors "github.com/pkg/errors"
78
)
89

910
// Config is the MySQL checker configuration settings container.
1011
type Config struct {
1112
// DSN is the MySQL instance connection DSN. Required.
1213
DSN string
13-
14-
// LogFunc is the callback function for errors logging during check.
15-
// If not set logging is skipped.
16-
LogFunc func(err error, details string, extra ...interface{})
1714
}
1815

1916
// New creates new MySQL health check that verifies the following:
2017
// - connection establishing
2118
// - doing the ping command
2219
// - selecting mysql version
2320
func New(config Config) func() error {
24-
if config.LogFunc == nil {
25-
config.LogFunc = func(err error, details string, extra ...interface{}) {}
26-
}
27-
28-
return func() error {
21+
return func() (checkErr error) {
2922
db, err := sql.Open("mysql", config.DSN)
3023
if err != nil {
31-
config.LogFunc(err, "MySQL health check failed during connect")
32-
return err
24+
checkErr = wErrors.Wrap(err, "MySQL health check failed on connect")
25+
return
3326
}
3427

3528
defer func() {
36-
if err = db.Close(); err != nil {
37-
config.LogFunc(err, "MySQL health check failed during connection closing")
29+
// override checkErr only if there were no other errors
30+
if err = db.Close(); err != nil && checkErr == nil {
31+
checkErr = wErrors.Wrap(err, "MySQL health check failed on connection closing")
3832
}
3933
}()
4034

4135
err = db.Ping()
4236
if err != nil {
43-
config.LogFunc(err, "MySQL health check failed during ping")
44-
return err
37+
checkErr = wErrors.Wrap(err, "MySQL health check failed on ping")
38+
return
4539
}
4640

4741
rows, err := db.Query(`SELECT VERSION()`)
4842
if err != nil {
49-
config.LogFunc(err, "MySQL health check failed during select")
50-
return err
43+
checkErr = wErrors.Wrap(err, "MySQL health check failed on select")
44+
return
5145
}
5246
defer func() {
53-
if err = rows.Close(); err != nil {
54-
config.LogFunc(err, "MySQL health check failed during rows closing")
47+
// override checkErr only if there were no other errors
48+
if err = rows.Close(); err != nil && checkErr == nil {
49+
checkErr = wErrors.Wrap(err, "MySQL health check failed on rows closing")
5550
}
5651
}()
5752

58-
return nil
53+
return
5954
}
6055
}

checks/postgres/check.go

+15-18
Original file line numberDiff line numberDiff line change
@@ -4,55 +4,52 @@ import (
44
"database/sql"
55

66
_ "github.com/lib/pq" // import pg driver
7+
wErrors "github.com/pkg/errors"
78
)
89

910
// Config is the PostgreSQL checker configuration settings container.
1011
type Config struct {
1112
// DSN is the PostgreSQL instance connection DSN. Required.
1213
DSN string
13-
// If not set logging is skipped.
14-
LogFunc func(err error, details string, extra ...interface{})
1514
}
1615

1716
// New creates new PostgreSQL health check that verifies the following:
1817
// - connection establishing
1918
// - doing the ping command
2019
// - selecting postgres version
2120
func New(config Config) func() error {
22-
if config.LogFunc == nil {
23-
config.LogFunc = func(err error, details string, extra ...interface{}) {}
24-
}
25-
26-
return func() error {
21+
return func() (checkErr error) {
2722
db, err := sql.Open("postgres", config.DSN)
2823
if err != nil {
29-
config.LogFunc(err, "PostgreSQL health check failed during connect")
30-
return err
24+
checkErr = wErrors.Wrap(err, "PostgreSQL health check failed on connect")
25+
return
3126
}
3227

3328
defer func() {
34-
if err = db.Close(); err != nil {
35-
config.LogFunc(err, "PostgreSQL health check failed during connection closing")
29+
// override checkErr only if there were no other errors
30+
if err := db.Close(); err != nil && checkErr == nil {
31+
checkErr = wErrors.Wrap(err, "PostgreSQL health check failed on connection closing")
3632
}
3733
}()
3834

3935
err = db.Ping()
4036
if err != nil {
41-
config.LogFunc(err, "PostgreSQL health check failed during ping")
42-
return err
37+
checkErr = wErrors.Wrap(err, "PostgreSQL health check failed on ping")
38+
return
4339
}
4440

4541
rows, err := db.Query(`SELECT VERSION()`)
4642
if err != nil {
47-
config.LogFunc(err, "PostgreSQL health check failed during select")
48-
return err
43+
checkErr = wErrors.Wrap(err, "PostgreSQL health check failed on select")
44+
return
4945
}
5046
defer func() {
51-
if err = rows.Close(); err != nil {
52-
config.LogFunc(err, "PostgreSQL health check failed during rows closing")
47+
// override checkErr only if there were no other errors
48+
if err = rows.Close(); err != nil && checkErr == nil {
49+
checkErr = wErrors.Wrap(err, "PostgreSQL health check failed on rows closing")
5350
}
5451
}()
5552

56-
return nil
53+
return
5754
}
5855
}

0 commit comments

Comments
 (0)