diff --git a/src/pkg/session/session.go b/src/pkg/session/session.go index c7a85813a..09640120d 100644 --- a/src/pkg/session/session.go +++ b/src/pkg/session/session.go @@ -2,6 +2,7 @@ package session import ( "context" + "errors" "fmt" "os" @@ -78,6 +79,10 @@ func (sl *SessionLoader) loadStack(ctx context.Context) (*stacks.Parameters, str } stack, whence, err := sl.sm.GetStack(ctx, sl.opts.GetStackOpts) if err != nil { + var notExistErr *stacks.ErrNotExist + if errors.As(err, ¬ExistErr) { + return nil, "", err + } if sl.opts.ProviderID != "" { whence = "--provider flag" } @@ -88,6 +93,9 @@ func (sl *SessionLoader) loadStack(ctx context.Context) (*stacks.Parameters, str if whence == "" { whence = "fallback stack" } + if sl.opts.ProviderID == client.ProviderAuto { + sl.opts.ProviderID = client.ProviderDefang + } return &stacks.Parameters{ Name: stacks.DefaultBeta, Provider: sl.opts.ProviderID, diff --git a/src/pkg/session/session_test.go b/src/pkg/session/session_test.go index 566a63e9e..ceb4ec3c9 100644 --- a/src/pkg/session/session_test.go +++ b/src/pkg/session/session_test.go @@ -94,6 +94,17 @@ func TestLoadSession(t *testing.T) { Name: "beta", }, }, + { + name: "specified non-existing stack", + options: SessionLoaderOptions{ + GetStackOpts: stacks.GetStackOpts{ + Stack: "missingstack", + }, + }, + + expectedError: "stack \"missingstack\" does not exist", + expectedEnv: map[string]string{}, + }, { name: "specified existing stack", options: SessionLoaderOptions{ @@ -151,7 +162,13 @@ func TestLoadSession(t *testing.T) { sm := &mockStacksManager{} if tt.existingStack == nil { - sm.On("GetStack", ctx, mock.Anything).Maybe().Return(nil, "", errors.New("stack not found")) + if tt.options.GetStackOpts.Stack != "" { + // For specified non-existing stack, return ErrNotExist + sm.On("GetStack", ctx, mock.Anything).Maybe().Return(nil, "", &stacks.ErrNotExist{StackName: tt.options.GetStackOpts.Stack}) + } else { + // For empty stack (should fall back to beta), return a general error that's not ErrNotExist + sm.On("GetStack", ctx, mock.Anything).Maybe().Return(nil, "", errors.New("no default stack set for project")) + } } else { sm.On("GetStack", ctx, mock.Anything).Maybe().Return(tt.existingStack, "local", nil) } diff --git a/src/pkg/stacks/manager.go b/src/pkg/stacks/manager.go index 34423d79a..9353b18bd 100644 --- a/src/pkg/stacks/manager.go +++ b/src/pkg/stacks/manager.go @@ -173,7 +173,7 @@ func (sm *manager) GetRemote(ctx context.Context, name string) (*Parameters, err } } if remoteStack == nil { - return nil, fmt.Errorf("unable to find stack %q", name) + return nil, &ErrNotExist{StackName: name} } return &remoteStack.Parameters, nil @@ -203,6 +203,14 @@ func (sl *manager) GetStack(ctx context.Context, opts GetStackOpts) (*Parameters return sl.getDefaultStack(ctx) } +type ErrNotExist struct { + StackName string +} + +func (e *ErrNotExist) Error() string { + return fmt.Sprintf("stack %q does not exist", e.StackName) +} + func (sm *manager) getSpecifiedStack(ctx context.Context, name string) (*Parameters, string, error) { whence := "--stack flag" _, envSet := os.LookupEnv("DEFANG_STACK") @@ -219,7 +227,7 @@ func (sm *manager) getSpecifiedStack(ctx context.Context, name string) (*Paramet // the stack file does not exist locally; try loading remotely stack, err = sm.GetRemote(ctx, name) if err != nil { - return nil, "", fmt.Errorf("failed to find stack file or previously deployed stack: %w", err) + return nil, "", err } // persist the remote stack file to the local target directory stackFilename, err := sm.Create(*stack) @@ -257,7 +265,7 @@ func (sm *manager) getDefaultStack(ctx context.Context) (*Parameters, string, er if connect.CodeOf(err) != connect.CodeNotFound { return nil, "", err } - term.Debugf("No default stack set for project %q; using default", sm.projectName) + term.Debugf("No default stack set for project %q; using fallback", sm.projectName) return nil, "", errors.New("no default stack set for project") } diff --git a/src/pkg/stacks/manager_test.go b/src/pkg/stacks/manager_test.go index 120de4f81..fef86a1d4 100644 --- a/src/pkg/stacks/manager_test.go +++ b/src/pkg/stacks/manager_test.go @@ -614,7 +614,7 @@ GOOGLE_REGION=us-central1 // Load should fail _, err = manager.Load(t.Context(), "teststack") require.Error(t, err, "Load() should fail when target directory is empty") - require.Contains(t, err.Error(), "unable to find stack \"teststack\"", "Expected specific error message about operation not allowed") + require.Contains(t, err.Error(), "stack \"teststack\" does not exist", "Expected specific error message about operation not allowed") } func TestManager_RemoteOperationsWorkRegardlessOfDirectory(t *testing.T) { @@ -666,7 +666,7 @@ func TestGetStack(t *testing.T) { options: GetStackOpts{ Stack: "missingstack", }, - expectedError: "unable to find stack", + expectedError: "stack \"missingstack\" does not exist", expectedEnv: map[string]string{}, }, {