Skip to content

Commit

Permalink
Return wrapped errors instead of logging
Browse files Browse the repository at this point in the history
  • Loading branch information
vgarvardt committed Apr 17, 2020
1 parent ec95d55 commit eb378f9
Show file tree
Hide file tree
Showing 14 changed files with 150 additions and 172 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import (
"net/http"
"time"

"github.com/hellofresh/health-go"
healthMysql "github.com/hellofresh/health-go/checks/mysql"
"github.com/hellofresh/health-go/v3"
healthMysql "github.com/hellofresh/health-go/v3/checks/mysql"
)

func main() {
Expand Down Expand Up @@ -69,8 +69,8 @@ import (
"time"

"github.com/go-chi/chi"
"github.com/hellofresh/health-go"
healthMysql "github.com/hellofresh/health-go/checks/mysql"
"github.com/hellofresh/health-go/v3"
healthMysql "github.com/hellofresh/health-go/v3/checks/mysql"
)

func main() {
Expand Down
8 changes: 4 additions & 4 deletions _examples/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import (
"net/http"
"time"

"github.com/hellofresh/health-go"
healthHttp "github.com/hellofresh/health-go/checks/http"
healthMySql "github.com/hellofresh/health-go/checks/mysql"
healthPg "github.com/hellofresh/health-go/checks/postgres"
"github.com/hellofresh/health-go/v3"
healthHttp "github.com/hellofresh/health-go/v3/checks/http"
healthMySql "github.com/hellofresh/health-go/v3/checks/mysql"
healthPg "github.com/hellofresh/health-go/v3/checks/postgres"
)

func main() {
Expand Down
22 changes: 8 additions & 14 deletions checks/http/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,36 @@ package http

import (
"context"
"errors"
"net/http"
"time"

wErrors "github.com/pkg/errors"
)

const defaultRequestTimeout = 5 * time.Second

// Config is the HTTP checker configuration settings container.
type Config struct {
// URL is the remote service health check URL.
URL string
// RequestTimeout is the duration that health check will try to consume published test message.
// If not set - 5 seconds
RequestTimeout time.Duration
// LogFunc is the callback function for errors logging during check.
// If not set logging is skipped.
LogFunc func(err error, details string, extra ...interface{})
}

// New creates new HTTP service health check that verifies the following:
// - connection establishing
// - getting response status from defined URL
// - verifying that status code is less than 500
func New(config Config) func() error {
if config.LogFunc == nil {
config.LogFunc = func(err error, details string, extra ...interface{}) {}
}

if config.RequestTimeout == 0 {
config.RequestTimeout = time.Second * 5
config.RequestTimeout = defaultRequestTimeout
}

return func() error {
req, err := http.NewRequest(http.MethodGet, config.URL, nil)
if err != nil {
config.LogFunc(err, "Creating the request for the health check failed")
return err
return wErrors.Wrap(err, "creating the request for the health check failed")
}

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

res, err := http.DefaultClient.Do(req)
if err != nil {
config.LogFunc(err, "Making the request for the health check failed")
return err
return wErrors.Wrap(err, "making the request for the health check failed")
}
defer res.Body.Close()

if res.StatusCode >= http.StatusInternalServerError {
return errors.New("remote service is not available at the moment")
return wErrors.New("remote service is not available at the moment")
}

return nil
Expand Down
18 changes: 9 additions & 9 deletions checks/http/check_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,6 @@ import (

const httpURLEnv = "HEALTH_GO_HTTP_URL"

func getURL(t *testing.T) string {
if httpURL, ok := os.LookupEnv(httpURLEnv); ok {
return httpURL
}

t.Fatalf("required env variable missing: %s", httpURLEnv)
return ""
}

func TestNew(t *testing.T) {
check := New(Config{
URL: getURL(t),
Expand All @@ -26,3 +17,12 @@ func TestNew(t *testing.T) {
err := check()
require.NoError(t, err)
}

func getURL(t *testing.T) string {
t.Helper()

httpURL, ok := os.LookupEnv(httpURLEnv)
require.True(t, ok)

return httpURL
}
34 changes: 15 additions & 19 deletions checks/mongo/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"time"

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

// TimeoutConnect defines timeout for establishing mongo connection, if not set - default value is used
TimeoutConnect time.Duration
Expand All @@ -35,10 +33,6 @@ type Config struct {
// - connection establishing
// - doing the ping command
func New(config Config) func() error {
if config.LogFunc == nil {
config.LogFunc = func(err error, details string, extra ...interface{}) {}
}

if config.TimeoutConnect == 0 {
config.TimeoutConnect = defaultTimeoutConnect
}
Expand All @@ -51,42 +45,44 @@ func New(config Config) func() error {
config.TimeoutPing = defaultTimeoutPing
}

return func() error {
return func() (checkErr error) {
var ctx context.Context
var cancel context.CancelFunc

client, err := mongo.NewClient(options.Client().ApplyURI(config.DSN))
if err != nil {
config.LogFunc(err, "MongoDB health check failed on client creation")
return err
checkErr = wErrors.Wrap(err, "mongoDB health check failed on client creation")
return
}

ctx, cancel = context.WithTimeout(context.Background(), config.TimeoutConnect)
defer cancel()
err = client.Connect(ctx)

err = client.Connect(ctx)
if err != nil {
config.LogFunc(err, "MongoDB health check failed on connect")
return err
checkErr = wErrors.Wrap(err, "mongoDB health check failed on connect")
return
}

defer func() {
ctx, cancel = context.WithTimeout(context.Background(), config.TimeoutDisconnect)
defer cancel()
if err := client.Disconnect(ctx); err != nil {
config.LogFunc(err, "MongoDB health check failed on closing connection")

// override checkErr only if there were no other errors
if err := client.Disconnect(ctx); err != nil && checkErr == nil {
checkErr = wErrors.Wrap(err, "mongoDB health check failed on closing connection")
}
}()

ctx, cancel = context.WithTimeout(context.Background(), config.TimeoutPing)
defer cancel()
err = client.Ping(ctx, readpref.Primary())

err = client.Ping(ctx, readpref.Primary())
if err != nil {
config.LogFunc(err, "MongoDB health check failed during ping")
return err
checkErr = wErrors.Wrap(err, "mongoDB health check failed on ping")
return
}

return nil
return
}
}
18 changes: 9 additions & 9 deletions checks/mongo/check_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,6 @@ import (

const mgDSNEnv = "HEALTH_GO_MG_DSN"

func getDSN(t *testing.T) string {
if mongoDSN, ok := os.LookupEnv(mgDSNEnv); ok {
return mongoDSN
}

t.Fatalf("required env variable missing: %s", mgDSNEnv)
return ""
}

func TestNew(t *testing.T) {
check := New(Config{
DSN: getDSN(t),
Expand All @@ -26,3 +17,12 @@ func TestNew(t *testing.T) {
err := check()
require.NoError(t, err)
}

func getDSN(t *testing.T) string {
t.Helper()

mongoDSN, ok := os.LookupEnv(mgDSNEnv)
require.True(t, ok)

return mongoDSN
}
35 changes: 15 additions & 20 deletions checks/mysql/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,57 +4,52 @@ import (
"database/sql"

_ "github.com/go-sql-driver/mysql" // import mysql driver
wErrors "github.com/pkg/errors"
)

// Config is the MySQL checker configuration settings container.
type Config struct {
// DSN is the MySQL instance connection DSN. Required.
DSN string

// LogFunc is the callback function for errors logging during check.
// If not set logging is skipped.
LogFunc func(err error, details string, extra ...interface{})
}

// New creates new MySQL health check that verifies the following:
// - connection establishing
// - doing the ping command
// - selecting mysql version
func New(config Config) func() error {
if config.LogFunc == nil {
config.LogFunc = func(err error, details string, extra ...interface{}) {}
}

return func() error {
return func() (checkErr error) {
db, err := sql.Open("mysql", config.DSN)
if err != nil {
config.LogFunc(err, "MySQL health check failed during connect")
return err
checkErr = wErrors.Wrap(err, "MySQL health check failed on connect")
return
}

defer func() {
if err = db.Close(); err != nil {
config.LogFunc(err, "MySQL health check failed during connection closing")
// override checkErr only if there were no other errors
if err = db.Close(); err != nil && checkErr == nil {
checkErr = wErrors.Wrap(err, "MySQL health check failed on connection closing")
}
}()

err = db.Ping()
if err != nil {
config.LogFunc(err, "MySQL health check failed during ping")
return err
checkErr = wErrors.Wrap(err, "MySQL health check failed on ping")
return
}

rows, err := db.Query(`SELECT VERSION()`)
if err != nil {
config.LogFunc(err, "MySQL health check failed during select")
return err
checkErr = wErrors.Wrap(err, "MySQL health check failed on select")
return
}
defer func() {
if err = rows.Close(); err != nil {
config.LogFunc(err, "MySQL health check failed during rows closing")
// override checkErr only if there were no other errors
if err = rows.Close(); err != nil && checkErr == nil {
checkErr = wErrors.Wrap(err, "MySQL health check failed on rows closing")
}
}()

return nil
return
}
}
33 changes: 15 additions & 18 deletions checks/postgres/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,55 +4,52 @@ import (
"database/sql"

_ "github.com/lib/pq" // import pg driver
wErrors "github.com/pkg/errors"
)

// Config is the PostgreSQL checker configuration settings container.
type Config struct {
// DSN is the PostgreSQL instance connection DSN. Required.
DSN string
// If not set logging is skipped.
LogFunc func(err error, details string, extra ...interface{})
}

// New creates new PostgreSQL health check that verifies the following:
// - connection establishing
// - doing the ping command
// - selecting postgres version
func New(config Config) func() error {
if config.LogFunc == nil {
config.LogFunc = func(err error, details string, extra ...interface{}) {}
}

return func() error {
return func() (checkErr error) {
db, err := sql.Open("postgres", config.DSN)
if err != nil {
config.LogFunc(err, "PostgreSQL health check failed during connect")
return err
checkErr = wErrors.Wrap(err, "PostgreSQL health check failed on connect")
return
}

defer func() {
if err = db.Close(); err != nil {
config.LogFunc(err, "PostgreSQL health check failed during connection closing")
// override checkErr only if there were no other errors
if err := db.Close(); err != nil && checkErr == nil {
checkErr = wErrors.Wrap(err, "PostgreSQL health check failed on connection closing")
}
}()

err = db.Ping()
if err != nil {
config.LogFunc(err, "PostgreSQL health check failed during ping")
return err
checkErr = wErrors.Wrap(err, "PostgreSQL health check failed on ping")
return
}

rows, err := db.Query(`SELECT VERSION()`)
if err != nil {
config.LogFunc(err, "PostgreSQL health check failed during select")
return err
checkErr = wErrors.Wrap(err, "PostgreSQL health check failed on select")
return
}
defer func() {
if err = rows.Close(); err != nil {
config.LogFunc(err, "PostgreSQL health check failed during rows closing")
// override checkErr only if there were no other errors
if err = rows.Close(); err != nil && checkErr == nil {
checkErr = wErrors.Wrap(err, "PostgreSQL health check failed on rows closing")
}
}()

return nil
return
}
}
Loading

0 comments on commit eb378f9

Please sign in to comment.