Skip to content

Extract duplicate error handling patterns into reusable helpers#811

Merged
lpcox merged 4 commits intomainfrom
copilot/remove-duplicate-code-patterns
Feb 7, 2026
Merged

Extract duplicate error handling patterns into reusable helpers#811
lpcox merged 4 commits intomainfrom
copilot/remove-duplicate-code-patterns

Conversation

Copy link
Contributor

Copilot AI commented Feb 7, 2026

Analysis identified 18 instances of duplicated error handling logic across internal/server/unified.go and internal/mcp/connection.go. This consolidates them into tested helper functions.

Changes

SDK CallToolResult Error Returns (16 instances)

  • Extracted newErrorCallToolResult(err error) (*sdk.CallToolResult, interface{}, error) helper
  • Replaces repeated pattern: return &sdk.CallToolResult{IsError: true}, nil, err
  • Affected: tool handlers, session initialization, backend communication
// Before (repeated 16 times)
if err != nil {
    return &sdk.CallToolResult{IsError: true}, nil, err
}

// After
if err != nil {
    return newErrorCallToolResult(err)
}

HTTP Connection Error Detection (2 instances)

  • Extracted isHTTPConnectionError(err error) bool helper
  • Consolidates network error classification (connection refused, no such host, network unreachable)
  • Affected: HTTP initialize and request paths
// Before (repeated 2 times)
if strings.Contains(err.Error(), "connection refused") ||
   strings.Contains(err.Error(), "no such host") ||
   strings.Contains(err.Error(), "network is unreachable") {
    // handle connection error
}

// After
if isHTTPConnectionError(err) {
    // handle connection error
}

Test Coverage

  • Added 8 test cases covering both helpers
  • Tests validate error propagation and proper nil handling

Notes

  • Third pattern (command error detection) had only 1 occurrence - not duplicated, no action taken
  • Added TODO for future improvement: replace string matching with *net.OpError type assertions

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • example.com
    • Triggering command: /tmp/go-build3296312196/b271/launcher.test /tmp/go-build3296312196/b271/launcher.test -test.testlogfile=/tmp/go-build3296312196/b271/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true ache/go/1.25.6/x/tmp/tmp.7JmQLDmIdb/golangci-lint-2.8.0-linux-amd64.tar.gz nto helper functREDACTED x_amd64/vet -pthread -Wl,--no-gc-sect-o -fmessage-length/tmp/go-build1663340372/b266/_pkg_.a x_amd64/vet -I ache/go/1.25.6/x-p -fPIC x_amd64/vet -pthread -Wl,--no-gc-sect-o -fmessage-length/tmp/go-build3296312196/b259/_pkg_.a x_amd64/vet (dns block)
    • Triggering command: /tmp/go-build3756687988/b271/launcher.test /tmp/go-build3756687988/b271/launcher.test -test.testlogfile=/tmp/go-build3756687988/b271/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true (dns block)
  • invalid-host-that-does-not-exist-12345.com
    • Triggering command: `/tmp/go-build3296312196/b259/config.test /tmp/go-build3296312196/b259/config.test -test.testlogfile=/tmp/go-build3296312196/b259/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true -c=4 -nolocalimports -importcfg /tmp/go-build1663340372/b283/importcfg -pack /home/REDACTED/work/gh-aw-mcpg/gh-aw-mcpg/internal/testutil/mcptest/example_test.go /home/REDACTED/work/gh-aw-mcpg/gh-aw-mcpg/internal/testutil/mcptest/gateway_integration_test.go 64/s�� ache/go/1.25.6/x64/src/net nto helper functions
  • Pattern 2 (High Priority): Extract SDK CallToolResult error returns
    • test x_amd64/vet --gdwarf-5 --64 -o x_amd64/vet` (dns block)
  • nonexistent.local
    • Triggering command: /tmp/go-build3296312196/b271/launcher.test /tmp/go-build3296312196/b271/launcher.test -test.testlogfile=/tmp/go-build3296312196/b271/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true ache/go/1.25.6/x/tmp/tmp.7JmQLDmIdb/golangci-lint-2.8.0-linux-amd64.tar.gz nto helper functREDACTED x_amd64/vet -pthread -Wl,--no-gc-sect-o -fmessage-length/tmp/go-build1663340372/b266/_pkg_.a x_amd64/vet -I ache/go/1.25.6/x-p -fPIC x_amd64/vet -pthread -Wl,--no-gc-sect-o -fmessage-length/tmp/go-build3296312196/b259/_pkg_.a x_amd64/vet (dns block)
    • Triggering command: /tmp/go-build3756687988/b271/launcher.test /tmp/go-build3756687988/b271/launcher.test -test.testlogfile=/tmp/go-build3756687988/b271/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true (dns block)
  • slow.example.com
    • Triggering command: /tmp/go-build3296312196/b271/launcher.test /tmp/go-build3296312196/b271/launcher.test -test.testlogfile=/tmp/go-build3296312196/b271/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true ache/go/1.25.6/x/tmp/tmp.7JmQLDmIdb/golangci-lint-2.8.0-linux-amd64.tar.gz nto helper functREDACTED x_amd64/vet -pthread -Wl,--no-gc-sect-o -fmessage-length/tmp/go-build1663340372/b266/_pkg_.a x_amd64/vet -I ache/go/1.25.6/x-p -fPIC x_amd64/vet -pthread -Wl,--no-gc-sect-o -fmessage-length/tmp/go-build3296312196/b259/_pkg_.a x_amd64/vet (dns block)
    • Triggering command: /tmp/go-build3756687988/b271/launcher.test /tmp/go-build3756687988/b271/launcher.test -test.testlogfile=/tmp/go-build3756687988/b271/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true (dns block)
  • this-host-does-not-exist-12345.com
    • Triggering command: /tmp/go-build668030957/b001/mcp.test /tmp/go-build668030957/b001/mcp.test -test.testlogfile=/tmp/go-build668030957/b001/testlog.txt -test.paniconexit0 -test.timeout=10m0s conf�� 64/src/runtime/c-c=4 credential.usern-nolocalimports .12/x64/bin/as (dns block)
    • Triggering command: /tmp/go-build3296312196/b280/mcp.test /tmp/go-build3296312196/b280/mcp.test -test.testlogfile=/tmp/go-build3296312196/b280/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true -c=4 -nolocalimports -importcfg /tmp/go-build3296312196/b282/importcfg -pack /home/REDACTED/work/gh-aw-mcpg/gh-aw-mcpg/internal/middleware/jqschema.go /home/REDACTED/work/gh-aw-mcpg/gh-aw-mcpg/internal/middleware/jqschema_bench_test.go (dns block)
    • Triggering command: /tmp/go-build3756687988/b280/mcp.test /tmp/go-build3756687988/b280/mcp.test -test.testlogfile=/tmp/go-build3756687988/b280/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>[duplicate-code] Duplicate Code Analysis Report - 3 Patterns Detected</issue_title>
<issue_description># 🔍 Duplicate Code Analysis Report

Analysis of commit 06ff18a

Summary

This analysis identified 3 significant duplication patterns across the Go codebase, primarily in error handling and HTTP connection logic. While the project has already refactored some areas (e.g., logger initialization with generics), several high-impact patterns remain.

Detected Patterns

This analysis found 3 significant duplication patterns:

  1. HTTP Connection Error Checking - Severity: Medium - See sub-issue [duplicate-code] Duplicate Code Pattern: HTTP Connection Error Checking #740
  2. SDK CallToolResult Error Returns - Severity: High - See sub-issue [duplicate-code] Duplicate Code Pattern: SDK CallToolResult Error Returns #741
  3. Command Error Detection Logic - Severity: Low - See sub-issue [duplicate-code] Duplicate Code Pattern: Command Error Detection Logic #742

Overall Impact

Next Steps

  1. Review individual pattern sub-issues for detailed analysis
  2. Prioritize refactoring based on severity and impact
  3. Create implementation plan for highest priority patterns

Analysis Metadata

  • Analyzed Files: 60+ Go files in internal/ directory
  • Detection Method: Serena semantic code analysis + pattern matching
  • Commit: 06ff18a
  • Analysis Date: 2026-02-06</issue_description>

Comments on the Issue (you are @copilot in this section)

Custom agent used: agentic-workflows
GitHub Agentic Workflows (gh-aw) - Create, debug, and upgrade AI-powered workflows with intelligent prompt routing


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 3 commits February 7, 2026 17:28
- Pattern 2 (High Priority): Extract SDK CallToolResult error returns
  - Created newErrorCallToolResult() helper in unified.go
  - Replaced 16 instances of duplicate error pattern
  - Added unit tests for the helper function

- Pattern 1 (Medium Priority): Extract HTTP connection error checking
  - Created isHTTPConnectionError() helper in connection.go
  - Replaced 2 instances of duplicate error detection
  - Added unit tests for the helper function

All existing tests pass. Total reduction: ~45 lines of duplicated code.

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
…ents

- Replace assert.AnError with realistic fmt.Errorf() in tests
- Add TODO comment acknowledging string-based error matching limitations
- Suggest future improvement to use type assertions for error classification

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix duplicate code patterns in Go codebase Extract duplicate error handling patterns into reusable helpers Feb 7, 2026
Copilot AI requested a review from lpcox February 7, 2026 17:32
@lpcox lpcox marked this pull request as ready for review February 7, 2026 17:41
Copilot AI review requested due to automatic review settings February 7, 2026 17:41
@lpcox lpcox merged commit d4dc29c into main Feb 7, 2026
5 checks passed
@lpcox lpcox deleted the copilot/remove-duplicate-code-patterns branch February 7, 2026 17:41
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR reduces duplicated error-handling logic by extracting repeated patterns into small helper functions in the server and MCP connection layers, and adds unit tests to cover the new helpers.

Changes:

  • Added newErrorCallToolResult(err) to standardize SDK tool error returns in UnifiedServer.
  • Added isHTTPConnectionError(err) to centralize HTTP backend connection error classification.
  • Added unit tests covering both helpers.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
internal/server/unified.go Replaces repeated CallToolResult{IsError:true} error returns with newErrorCallToolResult helper.
internal/server/call_tool_result_test.go Adds unit test for newErrorCallToolResult.
internal/mcp/connection.go Introduces isHTTPConnectionError and uses it in HTTP init/request error handling.
internal/mcp/connection_test.go Adds unit tests for isHTTPConnectionError.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +159 to +171
name string
err error
expectError bool
}{
{
name: "simple error",
err: fmt.Errorf("test error"),
expectError: true,
},
{
name: "formatted error",
err: fmt.Errorf("formatted error: %s", "test"),
expectError: true,
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expectError in the test case struct is never used (all assertions are unconditional). This is misleading/unused state—either remove the field or use it to drive assertions (e.g., to support a future nil-error case).

Suggested change
name string
err error
expectError bool
}{
{
name: "simple error",
err: fmt.Errorf("test error"),
expectError: true,
},
{
name: "formatted error",
err: fmt.Errorf("formatted error: %s", "test"),
expectError: true,
name string
err error
}{
{
name: "simple error",
err: fmt.Errorf("test error"),
},
{
name: "formatted error",
err: fmt.Errorf("formatted error: %s", "test"),

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[duplicate-code] Duplicate Code Analysis Report - 3 Patterns Detected

3 participants