From 69ad4ca54a53bc73cc21e237e9397fb03a336572 Mon Sep 17 00:00:00 2001 From: Houmgaor Date: Thu, 5 Mar 2026 23:25:00 +0100 Subject: [PATCH] fix: diagnose specific database connection errors at startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of a generic "Failed to ping" message, detect the actual cause and show a targeted fix: - net error → PostgreSQL not reachable, check if it's running - pq 28P01 → wrong password, update config.json - pq 3D000 → database doesn't exist, create it --- main.go | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/main.go b/main.go index edee6de24..013baecfb 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,7 @@ package main import ( - cfg "erupe-ce/config" + "errors" "flag" "fmt" "net" @@ -9,9 +9,11 @@ import ( "os/signal" "path/filepath" "runtime/debug" + "strings" "syscall" "time" + cfg "erupe-ce/config" "erupe-ce/common/gametime" "erupe-ce/server/api" "erupe-ce/server/channelserver" @@ -20,10 +22,9 @@ import ( "erupe-ce/server/migrations" "erupe-ce/server/setup" "erupe-ce/server/signserver" - "strings" "github.com/jmoiron/sqlx" - _ "github.com/lib/pq" + "github.com/lib/pq" "go.uber.org/zap" ) @@ -148,13 +149,44 @@ func main() { db, err := sqlx.Open("postgres", connectString) if err != nil { - preventClose(config, fmt.Sprintf("Database: Failed to open, %s", err.Error())) + preventClose(config, fmt.Sprintf( + "Database: Failed to open connection to %s:%d\nError: %s", + config.Database.Host, config.Database.Port, err.Error(), + )) } // Test the DB connection. err = db.Ping() if err != nil { - preventClose(config, fmt.Sprintf("Database: Failed to ping, %s", err.Error())) + dbAddr := fmt.Sprintf("%s:%d", config.Database.Host, config.Database.Port) + var hint string + var pqErr *pq.Error + var netErr *net.OpError + switch { + case errors.As(err, &netErr): + hint = fmt.Sprintf( + "Database: PostgreSQL is not reachable at %s\n"+ + " Check that PostgreSQL is running: systemctl status postgresql (or docker ps)\n"+ + " Using Docker? Run: cd docker && docker compose up db -d", + dbAddr, + ) + case errors.As(err, &pqErr) && pqErr.Code == "28P01": + hint = fmt.Sprintf( + "Database: Wrong password for user '%s' at %s\n"+ + " Update Database.Password in config.json to match your PostgreSQL password.", + config.Database.User, dbAddr, + ) + case errors.As(err, &pqErr) && pqErr.Code == "3D000": + hint = fmt.Sprintf( + "Database: Database '%s' does not exist on %s\n"+ + " Create it with: createdb -U %s %s", + config.Database.Database, dbAddr, + config.Database.User, config.Database.Database, + ) + default: + hint = fmt.Sprintf("Database: Failed to connect to %s — %s", dbAddr, err.Error()) + } + preventClose(config, hint) } // Configure connection pool to avoid exhausting PostgreSQL under load.