fix(web): return startup errors instead of panicking (#1620)

Replace server startup panics with returned errors, print actionable CLI
messages with exit status 1, and clarify the API token flags.

Add regressions for missing web authentication credentials.

Fixes GopeedLab/gopeed#1614
This commit is contained in:
OKAN TIKTAS authored and GitHub committed 2026-10-26 18:05:56 +08:00
1 parent 903c5c46c4
commit 7d423e2182
5 files changed
+55 -9

No files matched your search

+7 -1
View File
@@ -1,6 +1,9 @@
package main
import (
"fmt"
"os"
"github.com/GopeedLab/gopeed/cmd"
"github.com/GopeedLab/gopeed/pkg/rest/model"
)
@@ -13,5 +16,8 @@ func main() {
Storage: model.StorageBolt,
WebEnable: true,
}
cmd.Start(cfg)
if err := cmd.Start(cfg); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
+7 -5
View File
@@ -16,15 +16,16 @@ import (
//go:embed banner.txt
var banner string
func Start(cfg *model.StartConfig) {
fmt.Println(banner)
func Start(cfg *model.StartConfig) error {
srv, listener, err := rest.BuildServer(cfg)
if err != nil {
panic(err)
return err
}
fmt.Println(banner)
downloadCfg, err := rest.Downloader.GetConfig()
if err != nil {
panic(err)
listener.Close()
return err
}
if rest.Downloader.IsFirstLoad() {
// Set default download config
@@ -62,8 +63,9 @@ func Start(cfg *model.StartConfig) {
fmt.Printf("Server start success on http://%s\n", listener.Addr().String())
if err := srv.Serve(listener); err != nil && err != http.ErrServerClosed {
panic(err)
return err
}
return nil
}
func watchExit() {
+35
View File
@@ -0,0 +1,35 @@
package cmd
import (
"strings"
"testing"
"github.com/GopeedLab/gopeed/pkg/rest/model"
)
func TestStartInvalidWebAPITokenReturnsError(t *testing.T) {
tests := []struct {
name string
webAuth *model.WebAuth
}{
{name: "no credentials"},
{name: "missing username", webAuth: &model.WebAuth{Password: "secret"}},
{name: "missing password", webAuth: &model.WebAuth{Username: "gopeed"}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := Start(&model.StartConfig{
WebEnable: true,
ApiToken: "test-token",
WebAuth: tt.webAuth,
})
if err == nil {
t.Fatal("Start() error = nil, want web authentication validation error")
}
if !strings.Contains(err.Error(), "web authentication username and password are required") {
t.Fatalf("Start() error = %q, want missing web authentication credentials", err)
}
})
}
}
+2 -2
View File
@@ -52,8 +52,8 @@ func loadCliArgs() *args {
flag.StringVar(cfg.Username, "username", "gopeed", "Web Authentication Username")
cfg.Password = flag.String("p", "", "Web Authentication Password, if no password is set, web authentication will not be enabled")
flag.StringVar(cfg.Password, "password", "", "Web Authentication Password, if no password is set, web authentication will not be enabled")
cfg.ApiToken = flag.String("T", "", "API token, it must be configured when using HTTP API in the case of enabling web authentication")
flag.StringVar(cfg.ApiToken, "api-token", "", "API token, it must be configured when using HTTP API in the case of enabling web authentication")
cfg.ApiToken = flag.String("T", "", "API token (requires web authentication with username and password)")
flag.StringVar(cfg.ApiToken, "api-token", "", "API token (requires web authentication with username and password)")
flag.BoolVar(&cfg.MCPEnable, "mcp-enable", false, "Enable MCP endpoint")
cfg.TempDir = flag.String("temp-dir", "", "Temporary directory (defaults to the OS temporary directory)")
cfg.StorageDir = flag.String("d", "", "Storage directory")
+4 -1
View File
@@ -62,7 +62,10 @@ func main() {
WebFS: sub,
WebAuth: webAuth,
}
cmd.Start(cfg)
if err := cmd.Start(cfg); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
func isNotBlank(str *string) bool {