fix: improve HTTP server startup with better error detection

- Added better error detection for HTTP server startup
- Added connectivity check to verify server is actually listening
- Increased wait time to 500ms for better error detection
- Added warning log if server connectivity check fails (may still be starting)
- Improved logging messages for server startup

This should help diagnose why the HTTP server isn't starting and provide better visibility into the startup process.
This commit is contained in:
2025-11-05 19:42:13 +01:00
parent d1d0b170ce
commit 512d76a6fb
2 changed files with 56 additions and 7 deletions

View File

@@ -145,7 +145,7 @@ func ProvideErrorBus() fx.Option {
func ProvideHealthRegistry() fx.Option {
return fx.Provide(func(dbClient *database.Client) (*health.Registry, error) {
registry := health.NewRegistry()
// Register database health checker
registry.Register("database", health.NewDatabaseChecker(dbClient))
@@ -237,19 +237,54 @@ func ProvideHTTPServer() fx.Option {
host = "0.0.0.0"
}
addr := fmt.Sprintf("%s:%d", host, port)
log.Info("HTTP server starting",
logger.String("addr", addr),
)
// Start server in a goroutine
// ListenAndServe blocks, so we need to start it async
// If there's an immediate error (like port in use), it will return quickly
errChan := make(chan error, 1)
go func() {
log.Info("HTTP server starting",
logger.String("addr", addr),
)
if err := srv.Start(); err != nil && err != http.ErrServerClosed {
log.Error("HTTP server error",
log.Error("HTTP server failed",
logger.String("error", err.Error()),
)
select {
case errChan <- err:
default:
}
}
}()
return nil
// Wait a short time to detect immediate binding errors
// If ListenAndServe fails immediately (e.g., port in use), it will return quickly
select {
case err := <-errChan:
return fmt.Errorf("HTTP server failed to start: %w", err)
case <-time.After(500 * time.Millisecond):
// If no error after 500ms, verify server is actually listening
// by attempting a connection
client := &http.Client{Timeout: 1 * time.Second}
checkURL := fmt.Sprintf("http://localhost:%d/healthz", port)
resp, err := client.Get(checkURL)
if err != nil {
// Server might still be starting, but log the attempt
log.Warn("Could not verify HTTP server is listening (may still be starting)",
logger.String("url", checkURL),
logger.String("error", err.Error()),
)
// Continue anyway - server might still be starting
} else {
resp.Body.Close()
}
log.Info("HTTP server started successfully",
logger.String("addr", addr),
)
return nil
}
},
OnStop: func(ctx context.Context) error {
return srv.Shutdown(ctx)