Skip to content

Duplicate Code: HTTP server runner onError handler (routerlicious-base) #26597

@github-actions

Description

@github-actions

Analysis of commit 8fa20de

Assignee: @copilot

Summary

AlfredRunner, RiddlerRunner, and NexusRunner each implement an identical private onError(error) handler for the Node HTTP server "error" event. This is a clear copy/paste duplication (~26 lines) across 3 services that should be centralized to reduce maintenance and bug-fix drift.

Duplication Details

Pattern: identical HTTP listen error handling

  • Severity: Medium

  • Occurrences: 3

  • Locations:

    • server/routerlicious/packages/routerlicious-base/src/alfred/runner.ts (lines 160-186)
    • server/routerlicious/packages/routerlicious-base/src/riddler/runner.ts (lines 125-151)
    • server/routerlicious/packages/routerlicious-base/src/nexus/runner.ts (lines 194-220)
  • Code Sample (representative):

private onError(error) {
	if (!this.runnerMetric.isCompleted()) {
		this.runnerMetric.error(
			`${this.runnerMetric.eventName} encountered an error in http server`,
			error,
		);
	}
	if (error.syscall !== "listen") {
		throw error;
	}

	const bind = typeof this.port === "string" ? `Pipe ${this.port}` : `Port ${this.port}`;

	// Handle specific listen errors with friendly messages
	switch (error.code) {
		case "EACCES":
			this.runningDeferred?.reject(`${bind} requires elevated privileges`);
			this.runningDeferred = undefined;
			break;
		case "EADDRINUSE":
			this.runningDeferred?.reject(`${bind} is already in use`);
			this.runningDeferred = undefined;
			break;
		default:
			throw error;
	}
}

Impact Analysis

  • Maintainability: Any changes to listen-error handling, logging, or metric reporting must be replicated across 3 runners.
  • Bug Risk: High risk of inconsistent future behavior (e.g., adding a new error.code case or changing metric wording in only one runner).
  • Code Bloat: ~75 lines of repeated logic across the codebase.

Refactoring Recommendations

  1. Extract a shared helper in routerlicious-base, e.g. handleRunnerHttpServerError(...) or createListenErrorHandler(...).

    • Suggested location: server/routerlicious/packages/routerlicious-base/src/utils/runnerErrors.ts (or an existing shared util module)
    • Parameters likely needed: runnerMetric, runningDeferred, port
    • Benefits: single place to update logic and standardize logging/metrics.
  2. (Optional) If runners already share other lifecycle helpers, consider a small base class or composition helper that wires httpServer.on("error") and delegates to the shared implementation.

Implementation Checklist

  • Extract shared listen-error handler utility
  • Replace onError implementations in Alfred/Riddler/Nexus with calls to the shared helper
  • Ensure runnerMetric completion semantics remain unchanged
  • Run routerlicious-base tests / service startup smoke checks

Analysis Metadata

  • Analyzed Files: server/routerlicious/packages/routerlicious-base/src/{alfred,riddler,nexus}/runner.ts
  • Detection Method: Serena semantic scan + duplicate-window detection
  • Commit: 8fa20de
  • Analysis Date: 2026-03-01T07:54:49.900Z

AI generated by Duplicate Code Detector

To add this workflow in your repository, run gh aw add github/gh-aw/.github/workflows/duplicate-code-detector.md@94662b1dee8ce96c876ba9f33b3ab8be32de82a4. See usage guide.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions