From 5b8e975e3ab72a15153106ebaee756dd3eac14cd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 14 Jan 2026 05:14:51 +0000 Subject: [PATCH 1/3] Initial plan From b6a1bbe59ff386910274580def5cf19b4810e2a1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 14 Jan 2026 05:21:43 +0000 Subject: [PATCH 2/3] Fix interrupt error handling in middleware resolution When a user cancels a prompt (Ctrl+C) during middleware dependency resolution (e.g., during environment initialization), the interrupt error should be propagated immediately rather than being logged and ignored. This prevents panics from accessing nil pointers in subsequent code that expects initialized dependencies. Changes: - Import terminal package for InterruptErr - Check for interrupt error in middleware resolution - Return error immediately if interrupt is detected - Add unit test for interrupt error scenario Co-authored-by: vhvb1989 <24213737+vhvb1989@users.noreply.github.com> --- cli/azd/cmd/middleware/middleware.go | 6 ++++ cli/azd/cmd/middleware/middleware_test.go | 36 +++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/cli/azd/cmd/middleware/middleware.go b/cli/azd/cmd/middleware/middleware.go index ab413c50052..bd54052e71f 100644 --- a/cli/azd/cmd/middleware/middleware.go +++ b/cli/azd/cmd/middleware/middleware.go @@ -10,6 +10,7 @@ import ( "log" "slices" + "github.com/AlecAivazis/survey/v2/terminal" "github.com/azure/azure-dev/cli/azd/cmd/actions" "github.com/azure/azure-dev/cli/azd/pkg/ioc" "github.com/spf13/pflag" @@ -99,6 +100,11 @@ func (r *MiddlewareRunner) RunAction( var middleware Middleware if err := actionContainer.ResolveNamed(middlewareName, &middleware); err != nil { + // Check if the error is an interrupt error (user cancelled a prompt) + // In this case, we should not continue and return the error immediately + if errors.Is(err, terminal.InterruptErr) { + return nil, err + } log.Printf("failed resolving middleware '%s' : %v\n", middlewareName, err) } diff --git a/cli/azd/cmd/middleware/middleware_test.go b/cli/azd/cmd/middleware/middleware_test.go index cc7da658414..009dafc7df5 100644 --- a/cli/azd/cmd/middleware/middleware_test.go +++ b/cli/azd/cmd/middleware/middleware_test.go @@ -8,6 +8,7 @@ import ( "fmt" "testing" + "github.com/AlecAivazis/survey/v2/terminal" "github.com/azure/azure-dev/cli/azd/cmd/actions" "github.com/azure/azure-dev/cli/azd/test/mocks" "github.com/stretchr/testify/require" @@ -161,6 +162,41 @@ func Test_Middleware_RunAction(t *testing.T) { require.Nil(t, result) require.NoError(t, err) }) + + // Test that interrupt errors during middleware resolution are propagated and not ignored + t.Run("interrupt error during middleware resolution", func(t *testing.T) { + mockContext := mocks.NewMockContext(context.Background()) + middlewareRunner := NewMiddlewareRunner(mockContext.Container) + + // Register a middleware constructor that returns an interrupt error + // This simulates what happens when a user cancels a prompt during dependency initialization + err := middlewareRunner.Use("interrupt-middleware", func() (Middleware, error) { + return nil, terminal.InterruptErr + }) + require.NoError(t, err) + + // Register an action that should not run if interrupt occurs + actionRan := false + err = mockContext.Container.RegisterNamedTransient("test-action", func() actions.Action { + return &testAction{ + runFunc: func(ctx context.Context) (*actions.ActionResult, error) { + actionRan = true + return &actions.ActionResult{ + Message: &actions.ResultMessage{Header: "Action"}, + }, nil + }, + } + }) + require.NoError(t, err) + + result, err := middlewareRunner.RunAction(*mockContext.Context, &Options{Name: "test"}, "test-action") + + // Verify that the interrupt error is returned and the action does not run + require.Nil(t, result) + require.Error(t, err) + require.ErrorIs(t, err, terminal.InterruptErr) + require.False(t, actionRan) + }) } func registerAction(t *testing.T, mockContext *mocks.MockContext, name string, runLog *[]string) *bool { From 148e23b95d7c10e0f40c8fa82f54859de89026bd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 14 Jan 2026 05:25:43 +0000 Subject: [PATCH 3/3] Update progress - all checks passed Co-authored-by: vhvb1989 <24213737+vhvb1989@users.noreply.github.com> --- cli/azd/extensions/azure.ai.finetune/go.mod | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/azd/extensions/azure.ai.finetune/go.mod b/cli/azd/extensions/azure.ai.finetune/go.mod index 245759a75d1..ab3a8b87aec 100644 --- a/cli/azd/extensions/azure.ai.finetune/go.mod +++ b/cli/azd/extensions/azure.ai.finetune/go.mod @@ -10,7 +10,9 @@ require ( github.com/braydonk/yaml v0.9.0 github.com/fatih/color v1.18.0 github.com/openai/openai-go/v3 v3.2.0 + github.com/sethvargo/go-retry v0.3.0 github.com/spf13/cobra v1.10.1 + gopkg.in/yaml.v3 v3.0.1 ) require ( @@ -61,7 +63,6 @@ require ( github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/rivo/uniseg v0.4.7 // indirect - github.com/sethvargo/go-retry v0.3.0 // indirect github.com/spf13/pflag v1.0.10 // indirect github.com/stretchr/testify v1.11.1 // indirect github.com/theckman/yacspin v0.13.12 // indirect @@ -86,5 +87,4 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20251007200510-49b9836ed3ff // indirect google.golang.org/grpc v1.76.0 // indirect google.golang.org/protobuf v1.36.10 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect )