Skip to content

Commit 5d26bbe

Browse files
committed
Make pgconn.ConnectError and pgconn.ParseConfigError public
fixes #1773
1 parent 44768b5 commit 5d26bbe

File tree

4 files changed

+37
-35
lines changed

4 files changed

+37
-35
lines changed

pgconn/config.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -237,12 +237,12 @@ func ParseConfigWithOptions(connString string, options ParseConfigOptions) (*Con
237237
if strings.HasPrefix(connString, "postgres://") || strings.HasPrefix(connString, "postgresql://") {
238238
connStringSettings, err = parseURLSettings(connString)
239239
if err != nil {
240-
return nil, &parseConfigError{connString: connString, msg: "failed to parse as URL", err: err}
240+
return nil, &ParseConfigError{ConnString: connString, msg: "failed to parse as URL", err: err}
241241
}
242242
} else {
243243
connStringSettings, err = parseDSNSettings(connString)
244244
if err != nil {
245-
return nil, &parseConfigError{connString: connString, msg: "failed to parse as DSN", err: err}
245+
return nil, &ParseConfigError{ConnString: connString, msg: "failed to parse as DSN", err: err}
246246
}
247247
}
248248
}
@@ -251,7 +251,7 @@ func ParseConfigWithOptions(connString string, options ParseConfigOptions) (*Con
251251
if service, present := settings["service"]; present {
252252
serviceSettings, err := parseServiceSettings(settings["servicefile"], service)
253253
if err != nil {
254-
return nil, &parseConfigError{connString: connString, msg: "failed to read service", err: err}
254+
return nil, &ParseConfigError{ConnString: connString, msg: "failed to read service", err: err}
255255
}
256256

257257
settings = mergeSettings(defaultSettings, envSettings, serviceSettings, connStringSettings)
@@ -278,7 +278,7 @@ func ParseConfigWithOptions(connString string, options ParseConfigOptions) (*Con
278278
if connectTimeoutSetting, present := settings["connect_timeout"]; present {
279279
connectTimeout, err := parseConnectTimeoutSetting(connectTimeoutSetting)
280280
if err != nil {
281-
return nil, &parseConfigError{connString: connString, msg: "invalid connect_timeout", err: err}
281+
return nil, &ParseConfigError{ConnString: connString, msg: "invalid connect_timeout", err: err}
282282
}
283283
config.ConnectTimeout = connectTimeout
284284
config.DialFunc = makeConnectTimeoutDialFunc(connectTimeout)
@@ -340,7 +340,7 @@ func ParseConfigWithOptions(connString string, options ParseConfigOptions) (*Con
340340

341341
port, err := parsePort(portStr)
342342
if err != nil {
343-
return nil, &parseConfigError{connString: connString, msg: "invalid port", err: err}
343+
return nil, &ParseConfigError{ConnString: connString, msg: "invalid port", err: err}
344344
}
345345

346346
var tlsConfigs []*tls.Config
@@ -352,7 +352,7 @@ func ParseConfigWithOptions(connString string, options ParseConfigOptions) (*Con
352352
var err error
353353
tlsConfigs, err = configTLS(settings, host, options)
354354
if err != nil {
355-
return nil, &parseConfigError{connString: connString, msg: "failed to configure TLS", err: err}
355+
return nil, &ParseConfigError{ConnString: connString, msg: "failed to configure TLS", err: err}
356356
}
357357
}
358358

@@ -396,7 +396,7 @@ func ParseConfigWithOptions(connString string, options ParseConfigOptions) (*Con
396396
case "any":
397397
// do nothing
398398
default:
399-
return nil, &parseConfigError{connString: connString, msg: fmt.Sprintf("unknown target_session_attrs value: %v", tsa)}
399+
return nil, &ParseConfigError{ConnString: connString, msg: fmt.Sprintf("unknown target_session_attrs value: %v", tsa)}
400400
}
401401

402402
return config, nil

pgconn/errors.go

+12-10
Original file line numberDiff line numberDiff line change
@@ -57,22 +57,23 @@ func (pe *PgError) SQLState() string {
5757
return pe.Code
5858
}
5959

60-
type connectError struct {
61-
config *Config
60+
// ConnectError is the error returned when a connection attempt fails.
61+
type ConnectError struct {
62+
Config *Config // The configuration that was used in the connection attempt.
6263
msg string
6364
err error
6465
}
6566

66-
func (e *connectError) Error() string {
67+
func (e *ConnectError) Error() string {
6768
sb := &strings.Builder{}
68-
fmt.Fprintf(sb, "failed to connect to `host=%s user=%s database=%s`: %s", e.config.Host, e.config.User, e.config.Database, e.msg)
69+
fmt.Fprintf(sb, "failed to connect to `host=%s user=%s database=%s`: %s", e.Config.Host, e.Config.User, e.Config.Database, e.msg)
6970
if e.err != nil {
7071
fmt.Fprintf(sb, " (%s)", e.err.Error())
7172
}
7273
return sb.String()
7374
}
7475

75-
func (e *connectError) Unwrap() error {
76+
func (e *ConnectError) Unwrap() error {
7677
return e.err
7778
}
7879

@@ -88,21 +89,22 @@ func (e *connLockError) Error() string {
8889
return e.status
8990
}
9091

91-
type parseConfigError struct {
92-
connString string
92+
// ParseConfigError is the error returned when a connection string cannot be parsed.
93+
type ParseConfigError struct {
94+
ConnString string // The connection string that could not be parsed.
9395
msg string
9496
err error
9597
}
9698

97-
func (e *parseConfigError) Error() string {
98-
connString := redactPW(e.connString)
99+
func (e *ParseConfigError) Error() string {
100+
connString := redactPW(e.ConnString)
99101
if e.err == nil {
100102
return fmt.Sprintf("cannot parse `%s`: %s", connString, e.msg)
101103
}
102104
return fmt.Sprintf("cannot parse `%s`: %s (%s)", connString, e.msg, e.err.Error())
103105
}
104106

105-
func (e *parseConfigError) Unwrap() error {
107+
func (e *ParseConfigError) Unwrap() error {
106108
return e.err
107109
}
108110

pgconn/export_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
package pgconn
44

55
func NewParseConfigError(conn, msg string, err error) error {
6-
return &parseConfigError{
7-
connString: conn,
6+
return &ParseConfigError{
7+
ConnString: conn,
88
msg: msg,
99
err: err,
1010
}

pgconn/pgconn.go

+16-16
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,11 @@ func ConnectConfig(octx context.Context, config *Config) (pgConn *PgConn, err er
152152
ctx := octx
153153
fallbackConfigs, err = expandWithIPs(ctx, config.LookupFunc, fallbackConfigs)
154154
if err != nil {
155-
return nil, &connectError{config: config, msg: "hostname resolving error", err: err}
155+
return nil, &ConnectError{Config: config, msg: "hostname resolving error", err: err}
156156
}
157157

158158
if len(fallbackConfigs) == 0 {
159-
return nil, &connectError{config: config, msg: "hostname resolving error", err: errors.New("ip addr wasn't found")}
159+
return nil, &ConnectError{Config: config, msg: "hostname resolving error", err: errors.New("ip addr wasn't found")}
160160
}
161161

162162
foundBestServer := false
@@ -178,7 +178,7 @@ func ConnectConfig(octx context.Context, config *Config) (pgConn *PgConn, err er
178178
foundBestServer = true
179179
break
180180
} else if pgerr, ok := err.(*PgError); ok {
181-
err = &connectError{config: config, msg: "server error", err: pgerr}
181+
err = &ConnectError{Config: config, msg: "server error", err: pgerr}
182182
const ERRCODE_INVALID_PASSWORD = "28P01" // wrong password
183183
const ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION = "28000" // wrong password or bad pg_hba.conf settings
184184
const ERRCODE_INVALID_CATALOG_NAME = "3D000" // db does not exist
@@ -189,7 +189,7 @@ func ConnectConfig(octx context.Context, config *Config) (pgConn *PgConn, err er
189189
pgerr.Code == ERRCODE_INSUFFICIENT_PRIVILEGE {
190190
break
191191
}
192-
} else if cerr, ok := err.(*connectError); ok {
192+
} else if cerr, ok := err.(*ConnectError); ok {
193193
if _, ok := cerr.err.(*NotPreferredError); ok {
194194
fallbackConfig = fc
195195
}
@@ -199,7 +199,7 @@ func ConnectConfig(octx context.Context, config *Config) (pgConn *PgConn, err er
199199
if !foundBestServer && fallbackConfig != nil {
200200
pgConn, err = connect(ctx, config, fallbackConfig, true)
201201
if pgerr, ok := err.(*PgError); ok {
202-
err = &connectError{config: config, msg: "server error", err: pgerr}
202+
err = &ConnectError{Config: config, msg: "server error", err: pgerr}
203203
}
204204
}
205205

@@ -211,7 +211,7 @@ func ConnectConfig(octx context.Context, config *Config) (pgConn *PgConn, err er
211211
err := config.AfterConnect(ctx, pgConn)
212212
if err != nil {
213213
pgConn.conn.Close()
214-
return nil, &connectError{config: config, msg: "AfterConnect error", err: err}
214+
return nil, &ConnectError{Config: config, msg: "AfterConnect error", err: err}
215215
}
216216
}
217217

@@ -283,7 +283,7 @@ func connect(ctx context.Context, config *Config, fallbackConfig *FallbackConfig
283283
network, address := NetworkAddress(fallbackConfig.Host, fallbackConfig.Port)
284284
netConn, err := config.DialFunc(ctx, network, address)
285285
if err != nil {
286-
return nil, &connectError{config: config, msg: "dial error", err: normalizeTimeoutError(ctx, err)}
286+
return nil, &ConnectError{Config: config, msg: "dial error", err: normalizeTimeoutError(ctx, err)}
287287
}
288288

289289
pgConn.conn = netConn
@@ -295,7 +295,7 @@ func connect(ctx context.Context, config *Config, fallbackConfig *FallbackConfig
295295
pgConn.contextWatcher.Unwatch() // Always unwatch `netConn` after TLS.
296296
if err != nil {
297297
netConn.Close()
298-
return nil, &connectError{config: config, msg: "tls error", err: normalizeTimeoutError(ctx, err)}
298+
return nil, &ConnectError{Config: config, msg: "tls error", err: normalizeTimeoutError(ctx, err)}
299299
}
300300

301301
pgConn.conn = nbTLSConn
@@ -336,7 +336,7 @@ func connect(ctx context.Context, config *Config, fallbackConfig *FallbackConfig
336336
pgConn.frontend.Send(&startupMsg)
337337
if err := pgConn.flushWithPotentialWriteReadDeadlock(); err != nil {
338338
pgConn.conn.Close()
339-
return nil, &connectError{config: config, msg: "failed to write startup message", err: normalizeTimeoutError(ctx, err)}
339+
return nil, &ConnectError{Config: config, msg: "failed to write startup message", err: normalizeTimeoutError(ctx, err)}
340340
}
341341

342342
for {
@@ -346,7 +346,7 @@ func connect(ctx context.Context, config *Config, fallbackConfig *FallbackConfig
346346
if err, ok := err.(*PgError); ok {
347347
return nil, err
348348
}
349-
return nil, &connectError{config: config, msg: "failed to receive message", err: normalizeTimeoutError(ctx, err)}
349+
return nil, &ConnectError{Config: config, msg: "failed to receive message", err: normalizeTimeoutError(ctx, err)}
350350
}
351351

352352
switch msg := msg.(type) {
@@ -359,26 +359,26 @@ func connect(ctx context.Context, config *Config, fallbackConfig *FallbackConfig
359359
err = pgConn.txPasswordMessage(pgConn.config.Password)
360360
if err != nil {
361361
pgConn.conn.Close()
362-
return nil, &connectError{config: config, msg: "failed to write password message", err: err}
362+
return nil, &ConnectError{Config: config, msg: "failed to write password message", err: err}
363363
}
364364
case *pgproto3.AuthenticationMD5Password:
365365
digestedPassword := "md5" + hexMD5(hexMD5(pgConn.config.Password+pgConn.config.User)+string(msg.Salt[:]))
366366
err = pgConn.txPasswordMessage(digestedPassword)
367367
if err != nil {
368368
pgConn.conn.Close()
369-
return nil, &connectError{config: config, msg: "failed to write password message", err: err}
369+
return nil, &ConnectError{Config: config, msg: "failed to write password message", err: err}
370370
}
371371
case *pgproto3.AuthenticationSASL:
372372
err = pgConn.scramAuth(msg.AuthMechanisms)
373373
if err != nil {
374374
pgConn.conn.Close()
375-
return nil, &connectError{config: config, msg: "failed SASL auth", err: err}
375+
return nil, &ConnectError{Config: config, msg: "failed SASL auth", err: err}
376376
}
377377
case *pgproto3.AuthenticationGSS:
378378
err = pgConn.gssAuth()
379379
if err != nil {
380380
pgConn.conn.Close()
381-
return nil, &connectError{config: config, msg: "failed GSS auth", err: err}
381+
return nil, &ConnectError{Config: config, msg: "failed GSS auth", err: err}
382382
}
383383
case *pgproto3.ReadyForQuery:
384384
pgConn.status = connStatusIdle
@@ -396,7 +396,7 @@ func connect(ctx context.Context, config *Config, fallbackConfig *FallbackConfig
396396
return pgConn, nil
397397
}
398398
pgConn.conn.Close()
399-
return nil, &connectError{config: config, msg: "ValidateConnect failed", err: err}
399+
return nil, &ConnectError{Config: config, msg: "ValidateConnect failed", err: err}
400400
}
401401
}
402402
return pgConn, nil
@@ -407,7 +407,7 @@ func connect(ctx context.Context, config *Config, fallbackConfig *FallbackConfig
407407
return nil, ErrorResponseToPgError(msg)
408408
default:
409409
pgConn.conn.Close()
410-
return nil, &connectError{config: config, msg: "received unexpected message", err: err}
410+
return nil, &ConnectError{Config: config, msg: "received unexpected message", err: err}
411411
}
412412
}
413413
}

0 commit comments

Comments
 (0)