Skip to content

Commit 536fb51

Browse files
authored
Merge pull request #461 from docker/client/available
feat: check dial errors and return appropriate error
2 parents fa01502 + 4b1860b commit 536fb51

2 files changed

Lines changed: 45 additions & 2 deletions

File tree

client/client.go

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package client
1717
import (
1818
"context"
1919
"errors"
20+
"fmt"
2021
"net"
2122
"net/http"
2223
"time"
@@ -43,7 +44,8 @@ var (
4344
ParsePattern = secrets.ParsePattern
4445
MustParsePattern = secrets.MustParsePattern
4546

46-
ErrSecretNotFound = secrets.ErrNotFound
47+
ErrSecretNotFound = secrets.ErrNotFound
48+
ErrSecretsEngineNotAvailable = errors.New("secrets engine is not available")
4749
)
4850

4951
var _ secrets.Resolver = &client{}
@@ -121,7 +123,14 @@ type client struct {
121123
}
122124

123125
func (c client) GetSecrets(ctx context.Context, pattern secrets.Pattern) ([]secrets.Envelope, error) {
124-
return c.resolverClient.GetSecrets(ctx, pattern)
126+
envelopes, err := c.resolverClient.GetSecrets(ctx, pattern)
127+
if isDialError(err) {
128+
return nil, fmt.Errorf("%w: %w", ErrSecretsEngineNotAvailable, err)
129+
}
130+
if err != nil {
131+
return nil, err
132+
}
133+
return envelopes, nil
125134
}
126135

127136
type Client interface {
@@ -130,6 +139,17 @@ type Client interface {
130139
ListPlugins(ctx context.Context) ([]PluginInfo, error)
131140
}
132141

142+
func isDialError(err error) bool {
143+
if err == nil {
144+
return false
145+
}
146+
var oe *net.OpError
147+
if errors.As(err, &oe) && (oe.Op == "dial" || oe.Op == "connect") {
148+
return true
149+
}
150+
return false
151+
}
152+
133153
func New(options ...Option) (Client, error) {
134154
cfg := &config{
135155
requestTimeout: api.DefaultClientRequestTimeout,
@@ -173,6 +193,9 @@ func New(options ...Option) (Client, error) {
173193
func (c client) ListPlugins(ctx context.Context) ([]PluginInfo, error) {
174194
req := connect.NewRequest(v1.ListPluginsRequest_builder{}.Build())
175195
resp, err := c.listClient.ListPlugins(ctx, req)
196+
if isDialError(err) {
197+
return nil, fmt.Errorf("%w: %w", ErrSecretsEngineNotAvailable, err)
198+
}
176199
if err != nil {
177200
return nil, err
178201
}

client/client_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,23 @@ func Test_ListPlugins(t *testing.T) {
154154
}, result)
155155
})
156156
}
157+
158+
func TestSecretsEngineUnavailable(t *testing.T) {
159+
socketPath := testhelper.RandomShortSocketName()
160+
client, err := New(WithSocketPath(socketPath))
161+
require.NoError(t, err)
162+
_, err = client.ListPlugins(t.Context())
163+
require.ErrorIs(t, err, ErrSecretsEngineNotAvailable)
164+
_, err = client.GetSecrets(t.Context(), secrets.MustParsePattern("**"))
165+
require.ErrorIs(t, err, ErrSecretsEngineNotAvailable)
166+
}
167+
168+
func TestIsDialError(t *testing.T) {
169+
require.True(t, isDialError(&net.OpError{
170+
Op: "dial",
171+
}))
172+
require.True(t, isDialError(&net.OpError{
173+
Op: "connect",
174+
}))
175+
require.False(t, isDialError(nil))
176+
}

0 commit comments

Comments
 (0)