Skip to content

fix(gofr): warn when readiness checks are registered but the HTTP server never starts - #4260

Open
ikio-nen wants to merge 1 commit into
gofr-dev:developmentfrom
ikio-nen:fix/warn-no-routes-health-unreachable
Open

ikio-nen wants to merge 1 commit into
gofr-dev:developmentfrom
ikio-nen:fix/warn-no-routes-health-unreachable

Conversation

@ikio-nen

Copy link
Copy Markdown

Closes #4259.

Problem

An app that registers readiness checks but no HTTP routes never starts its HTTP server — silently:

app := gofr.New()
app.AddReadinessCheck(func(ctx *gofr.Context) error { return sqlPing(ctx) })
app.Run() // starts metrics only; /.well-known/health is never served

Run() gates startHTTPServer on httpRegistered, which is set only by route registration (GET/POST/GraphQL/CRUD) or the presence of a public/ static directory. With no routes and no public/, no port is bound, /.well-known/health is never served, and the startup log shows a perfectly healthy metrics server — while every readiness probe gets connection refused. Nothing says why.

The check-only app is unusual, but the failure is invisible when it happens: the metrics-port line in the log looks exactly like a normal startup.

Fix

startHTTPServer now logs a warning when it detects exactly that mismatch — readiness checks registered, HTTP server not marked for startup:

readiness: 1 app check(s) registered, but the HTTP server will not start — no route was registered and no public/ directory exists, so /.well-known/health is unreachable. Register at least one HTTP route.

The wording mirrors the existing readiness: N app check(s) registered info line, so both ends of the story read the same. Apps without readiness checks are unaffected and stay silent, so normal no-HTTP usage (pure metrics, gRPC-only, CMD) sees no new output.

Behavior change

None beyond the new WARN line: no API change, no config change, no startup-time cost for apps without readiness checks (the check is one nil-slice length read on a path that previously did nothing).

Verification

  • New test TestApp_startHTTPServer_warnsWhenReadinessChecksCannotBeServed drives the real startHTTPServer: warns with checks + no routes, stays silent with neither. It pins httpRegistered explicitly because New() marks the server for startup whenever the working directory happens to contain a static directory — a workspace-dependent test would be flaky.
  • End-to-end on a real app (register one readiness check, no routes): warning present in the startup log; with the /ping route added back, the warning disappears and health serves normally.
  • go vet ./pkg/gofr/ clean; gofmt clean.

Checklist

  • Formatted with gofmt (golangci-lint runs in CI).
  • New code covered by unit tests.
  • No decrease in overall code coverage.
  • Code comments reviewed for clarity.

…ver never starts

An app that registers readiness checks via AddReadinessCheck but registers no
HTTP routes — and has no public/ directory — starts metrics-only: Run() skips
startHTTPServer because httpRegistered is false, no port is bound, and
/.well-known/health is never served. Nothing in the startup log says why, so
the app looks healthy while every readiness probe gets connection refused.

startHTTPServer now logs a warning when it detects exactly that mismatch
(readiness checks registered, HTTP server not marked for startup), pointing at
the fix — register at least one HTTP route. Apps without readiness checks are
unaffected and stay silent.

Covered by TestApp_startHTTPServer_warnsWhenReadinessChecksCannotBeServed.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
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.

App with readiness checks but no HTTP routes silently never serves /.well-known/health

1 participant