Skip to content

Commit 039d0ce

Browse files
authored
Improve error when loading pod that doesn't exist (#319)
1 parent b36a616 commit 039d0ce

3 files changed

Lines changed: 65 additions & 0 deletions

File tree

internal/emulator/aws/client.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,14 @@ func isInvalidSnapshotFileMsg(msg string) bool {
239239
return strings.Contains(m, "not a valid zip archive") || strings.Contains(m, "invalid pod file")
240240
}
241241

242+
// isPodNotFoundMsg reports whether an emulator error message indicates the
243+
// requested cloud snapshot does not exist. The emulator reports an unknown pod
244+
// with this generic version-lookup message rather than a distinct not-found
245+
// error, so we translate it into snapshot.ErrPodNotFound.
246+
func isPodNotFoundMsg(msg string) bool {
247+
return strings.Contains(strings.ToLower(msg), "failed to get version information from platform")
248+
}
249+
242250
func (c *Client) LoadPodSnapshot(ctx context.Context, host, podName, authToken, strategy string) ([]string, error) {
243251
url := fmt.Sprintf("http://%s/_localstack/pods/%s", host, podName)
244252
if strategy != "" {
@@ -300,6 +308,9 @@ func (c *Client) LoadPodSnapshot(ctx context.Context, host, podName, authToken,
300308
if isInvalidSnapshotFileMsg(event.Message) {
301309
return nil, snapshot.ErrInvalidSnapshotFile
302310
}
311+
if isPodNotFoundMsg(event.Message) {
312+
return nil, snapshot.ErrPodNotFound
313+
}
303314
return nil, fmt.Errorf("pod load failed: %s", event.Message)
304315
}
305316
return services, nil

internal/snapshot/load.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,16 @@ func load(ctx context.Context, rt runtime.Runtime, containers []config.Container
109109
})
110110
return output.NewSilentError(err)
111111
}
112+
if errors.Is(err, ErrPodNotFound) {
113+
sink.Emit(output.ErrorEvent{
114+
Title: "Could not load snapshot",
115+
Summary: "Snapshot was not found on the LocalStack platform",
116+
Actions: []output.ErrorAction{
117+
{Label: "List your snapshots:", Value: "lstk snapshot list"},
118+
},
119+
})
120+
return output.NewSilentError(err)
121+
}
112122
return err
113123
}
114124

test/integration/snapshot_load_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,24 @@ func mockPodLoadServer(t *testing.T, respondOK bool) *httptest.Server {
7878
return srv
7979
}
8080

81+
// mockPodNotFoundServer mimics the emulator response when the requested cloud
82+
// snapshot does not exist: the platform version lookup fails, so the load
83+
// completes with the generic "Failed to get version information" diagnostic.
84+
func mockPodNotFoundServer(t *testing.T) *httptest.Server {
85+
t.Helper()
86+
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
87+
if strings.HasPrefix(r.URL.Path, "/_localstack/pods/") && r.Method == http.MethodPut {
88+
w.Header().Set("Content-Type", "application/x-ndjson")
89+
w.WriteHeader(http.StatusOK)
90+
_, _ = w.Write([]byte(`{"event":"completion","status":"error","message":"Failed to get version information from platform.. aborting"}` + "\n"))
91+
return
92+
}
93+
w.WriteHeader(http.StatusNotFound)
94+
}))
95+
t.Cleanup(srv.Close)
96+
return srv
97+
}
98+
8199
// writeTestSnapFile creates a small file usable as a local snapshot source.
82100
func writeTestSnapFile(t *testing.T, dir, name string) string {
83101
t.Helper()
@@ -294,6 +312,32 @@ func TestSnapshotLoadPodServerError(t *testing.T) {
294312
assert.Contains(t, stderr, "platform unavailable")
295313
}
296314

315+
// TestSnapshotLoadPodNotFound covers a non-existent cloud snapshot. The emulator
316+
// cannot fetch version information for an unknown pod and reports the generic
317+
// platform diagnostic; lstk must translate it into a clear "not found" message
318+
// rather than leaking "Failed to get version information from platform".
319+
func TestSnapshotLoadPodNotFound(t *testing.T) {
320+
requireDocker(t)
321+
cleanup()
322+
t.Cleanup(cleanup)
323+
324+
ctx := testContext(t)
325+
startTestContainer(t, ctx)
326+
srv := mockPodNotFoundServer(t)
327+
328+
stdout, stderr, err := runLstk(t, ctx, t.TempDir(),
329+
env.Environ(testEnvWithHome(t.TempDir(), "")).
330+
With(env.LocalStackHost, lsHost(srv)).
331+
With(env.AuthToken, "test-token"),
332+
"--non-interactive", "snapshot", "load", "pod:does-not-exist",
333+
)
334+
requireExitCode(t, 1, err)
335+
// The user-facing error is emitted through the sink (stdout); the raw
336+
// platform diagnostic must not leak to the user.
337+
assert.Contains(t, stdout, "not found on the LocalStack platform")
338+
assert.NotContains(t, strings.ToLower(stdout+stderr), "version information")
339+
}
340+
297341
func TestSnapshotLoadTelemetryEmitted(t *testing.T) {
298342
requireDocker(t)
299343
cleanup()

0 commit comments

Comments
 (0)