Skip to content

Commit b5e9726

Browse files
committed
Handle when error is not a pqerror
``` panic: interface conversion: error is *net.OpError, not *pq.Error [recovered] panic: interface conversion: error is *net.OpError, not *pq.Error ```
1 parent b5acc86 commit b5e9726

28 files changed

+2693
-5
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ require (
2626
github.com/Azure/go-autorest/autorest/date v0.2.0 // indirect
2727
github.com/Azure/go-autorest/logger v0.1.0 // indirect
2828
github.com/Azure/go-autorest/tracing v0.5.0 // indirect
29+
github.com/DATA-DOG/go-sqlmock v1.5.2 // indirect
2930
github.com/PuerkitoBio/purell v1.1.1 // indirect
3031
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
3132
github.com/beorn7/perks v1.0.1 // indirect

go.sum

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ
5050
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
5151
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
5252
github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
53+
github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU=
54+
github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU=
5355
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
5456
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
5557
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
@@ -517,6 +519,7 @@ github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALr
517519
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
518520
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
519521
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
522+
github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE=
520523
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
521524
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
522525
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=

pkg/postgres/role.go

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,30 @@ const (
1919
REASIGN_OBJECTS = `REASSIGN OWNED BY "%s" TO "%s"`
2020
)
2121

22+
func isPQError(err error, codes ...pq.ErrorCode) bool {
23+
if err == nil {
24+
return false
25+
}
26+
27+
pgError, ok := err.(*pq.Error)
28+
if ok {
29+
if len(codes) == 0 {
30+
// just checking if its a pgerror
31+
return true
32+
}
33+
for _, code := range codes {
34+
if pgError.Code == code {
35+
return true
36+
}
37+
}
38+
}
39+
return false
40+
}
41+
2242
func (c *pg) CreateGroupRole(role string) error {
2343
// Error code 42710 is duplicate_object (role already exists)
2444
_, err := c.db.Exec(fmt.Sprintf(CREATE_GROUP_ROLE, role))
25-
if err != nil && err.(*pq.Error).Code != "42710" {
45+
if err != nil && !isPQError(err, "42710") {
2646
return err
2747
}
2848
return nil
@@ -64,7 +84,7 @@ func (c *pg) DropRole(role, newOwner, database string, logger logr.Logger) error
6484
// REASSIGN OWNED BY only works if the correct database is selected
6585
tmpDb, err := GetConnection(c.user, c.pass, c.host, c.port, database, c.args, logger)
6686
if err != nil {
67-
if err.(*pq.Error).Code == "3D000" {
87+
if isPQError(err, "3D000") {
6888
return nil // Database is does not exist (anymore)
6989
} else {
7090
return err
@@ -73,20 +93,20 @@ func (c *pg) DropRole(role, newOwner, database string, logger logr.Logger) error
7393
_, err = tmpDb.Exec(fmt.Sprintf(REASIGN_OBJECTS, role, newOwner))
7494
defer tmpDb.Close()
7595
// Check if error exists and if different from "ROLE NOT FOUND" => 42704
76-
if err != nil && err.(*pq.Error).Code != "42704" {
96+
if err != nil && isPQError(err, "42704") {
7797
return err
7898
}
7999

80100
// We previously assigned all objects to the operator's role so DROP OWNED BY will drop privileges of role
81101
_, err = tmpDb.Exec(fmt.Sprintf(DROP_OWNED_BY, role))
82102
// Check if error exists and if different from "ROLE NOT FOUND" => 42704
83-
if err != nil && err.(*pq.Error).Code != "42704" {
103+
if err != nil && isPQError(err, "42704") {
84104
return err
85105
}
86106

87107
_, err = c.db.Exec(fmt.Sprintf(DROP_ROLE, role))
88108
// Check if error exists and if different from "ROLE NOT FOUND" => 42704
89-
if err != nil && err.(*pq.Error).Code != "42704" {
109+
if err != nil && isPQError(err, "42704") {
90110
return err
91111
}
92112
return nil

pkg/postgres/role_test.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package postgres
2+
3+
import (
4+
"errors"
5+
"testing"
6+
7+
"github.com/DATA-DOG/go-sqlmock"
8+
"github.com/lib/pq"
9+
)
10+
11+
func TestIsPQError(t *testing.T) {
12+
genericError := errors.New("regular error")
13+
14+
pqError := new(pq.Error)
15+
pqError.Code = "42710"
16+
17+
if isPQError(genericError, "42710") {
18+
t.Fatalf("generic error is not an pq error")
19+
}
20+
21+
if isPQError(pqError, "111111") {
22+
t.Fatalf("might be a pq error, but isn't this specific one")
23+
}
24+
25+
if !isPQError(pqError, "42710") {
26+
t.Fatalf("should match targeted pqerror")
27+
}
28+
29+
// multiple
30+
if !isPQError(pqError, "42710", "111111") {
31+
t.Fatalf("should match targeted pqerror")
32+
}
33+
}
34+
35+
func TestCreateGroupRole(t *testing.T) {
36+
db, mock, err := sqlmock.New()
37+
if err != nil {
38+
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
39+
}
40+
41+
defer db.Close()
42+
43+
duplicateObjectPGError := new(pq.Error)
44+
duplicateObjectPGError.Code = "42710" // duplicate_object
45+
46+
diskFullError := new(pq.Error)
47+
diskFullError.Code = "53100" // disk_full
48+
49+
mock.ExpectExec(`CREATE ROLE "working"`).WillReturnResult(sqlmock.NewResult(1, 1))
50+
mock.ExpectExec(`CREATE ROLE "already-exists"`).WillReturnError(duplicateObjectPGError)
51+
mock.ExpectExec(`CREATE ROLE "disk-full"`).WillReturnError(diskFullError)
52+
53+
pgObj := &pg{db: db}
54+
if err := pgObj.CreateGroupRole("working"); err != nil {
55+
t.Errorf("error calling create role: %s", err)
56+
}
57+
58+
if err := pgObj.CreateGroupRole("already-exists"); err != nil {
59+
t.Errorf("error calling create role: %s", err)
60+
}
61+
62+
if err := pgObj.CreateGroupRole("disk-full"); err == nil {
63+
t.Errorf("non ignored error didn't throw error")
64+
}
65+
66+
// we make sure that all expectations were met
67+
if err := mock.ExpectationsWereMet(); err != nil {
68+
t.Errorf("there were unfulfilled expectations: %s", err)
69+
}
70+
}

vendor/github.com/DATA-DOG/go-sqlmock/.gitignore

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/DATA-DOG/go-sqlmock/.travis.yml

Lines changed: 29 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/DATA-DOG/go-sqlmock/LICENSE

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)