From f26aac103baeb2853869814d69f1977323c3acd3 Mon Sep 17 00:00:00 2001 From: XingfenD Date: Mon, 14 Sep 2026 19:37:26 +0800 Subject: [PATCH] fix(config): validate DATABASE_URL required and parseable, log redis disabled (B15) --- backend/internal/config/config.go | 15 +++++++++++++++ backend/internal/config/config_test.go | 16 ++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/backend/internal/config/config.go b/backend/internal/config/config.go index 8e06393..394ac8c 100644 --- a/backend/internal/config/config.go +++ b/backend/internal/config/config.go @@ -2,11 +2,14 @@ package config import ( "fmt" + "log" "os" "path/filepath" "strconv" "strings" "time" + + "github.com/jackc/pgx/v5/pgxpool" ) type Config struct { @@ -52,6 +55,18 @@ func Load() (*Config, error) { if secret == "" { return nil, fmt.Errorf("JWT_SECRET required") } + // Validate required fields. + dbURL := env("DATABASE_URL", "") + if dbURL == "" { + return nil, fmt.Errorf("DATABASE_URL is required") + } + if _, perr := pgxpool.ParseConfig(dbURL); perr != nil { + return nil, fmt.Errorf("DATABASE_URL: %w", perr) + } + if env("REDIS_URL", "") == "" { + log.Printf("redis disabled: rate-limit/scan-lock/page-cache off") + } + // resolveDir: macOS 开发机上 /var、/tmp 是指向 /private 的软链, // 启动时解析一次才能让 root_path 前缀校验对上真实路径;目录不存在/出错则保留原值(Docker 路径不受影响) resolveDir := func(dir string) string { diff --git a/backend/internal/config/config_test.go b/backend/internal/config/config_test.go index c6fd5c0..1db8cf9 100644 --- a/backend/internal/config/config_test.go +++ b/backend/internal/config/config_test.go @@ -6,6 +6,22 @@ import ( "time" ) +func TestLoadDatabaseURLRequired(t *testing.T) { + t.Setenv("JWT_SECRET", "x") + t.Setenv("DATABASE_URL", "") + if _, err := Load(); err == nil { + t.Fatal("empty DATABASE_URL must fail") + } +} + +func TestLoadDatabaseURLMalformed(t *testing.T) { + t.Setenv("JWT_SECRET", "x") + t.Setenv("DATABASE_URL", "not a url") + if _, err := Load(); err == nil { + t.Fatal("malformed DATABASE_URL must fail") + } +} + func TestLoad(t *testing.T) { // 屏蔽外部 env,保证默认值断言自洽(Load 将空串视为未设置) t.Setenv("BOOKS_DIR", "")