From 20a72df439d76747c8675e3b6d5e460f01e3c311 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 23 Apr 2024 10:46:09 +0200 Subject: [PATCH 1/3] Improve error messages for not ready API endpoints --- api/endpoints.go | 2 +- api/router.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/endpoints.go b/api/endpoints.go index 2936930..7ea23a1 100644 --- a/api/endpoints.go +++ b/api/endpoints.go @@ -381,7 +381,7 @@ func (e *Endpoint) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Wait for the owning module to be ready. if !moduleIsReady(e.BelongsTo) { - http.Error(w, "The API endpoint is not ready yet or the its module is not enabled. Please try again later.", http.StatusServiceUnavailable) + http.Error(w, "The API endpoint is not ready yet or the its module is not enabled. Reload (F5) to try again.", http.StatusServiceUnavailable) return } diff --git a/api/router.go b/api/router.go index f43bef7..470a272 100644 --- a/api/router.go +++ b/api/router.go @@ -271,7 +271,7 @@ func (mh *mainHandler) handle(w http.ResponseWriter, r *http.Request) error { // Wait for the owning module to be ready. if moduleHandler, ok := handler.(ModuleHandler); ok { if !moduleIsReady(moduleHandler.BelongsTo()) { - http.Error(lrw, "The API endpoint is not ready yet. Please try again later.", http.StatusServiceUnavailable) + http.Error(lrw, "The API endpoint is not ready yet. Reload (F5) to try again.", http.StatusServiceUnavailable) return nil } } From b15a4aac466a6d2d5cbbb5ff01c71c279ac5188e Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 23 Apr 2024 10:46:50 +0200 Subject: [PATCH 2/3] Add ready API endpoint and temporarily "backport" to ping --- api/endpoints_debug.go | 25 +++++++++++++++++++++++++ modules/start.go | 5 +++++ 2 files changed, 30 insertions(+) diff --git a/api/endpoints_debug.go b/api/endpoints_debug.go index aed729f..2157b70 100644 --- a/api/endpoints_debug.go +++ b/api/endpoints_debug.go @@ -3,6 +3,7 @@ package api import ( "bytes" "context" + "errors" "fmt" "net/http" "os" @@ -11,6 +12,7 @@ import ( "time" "github.com/safing/portbase/info" + "github.com/safing/portbase/modules" "github.com/safing/portbase/utils/debug" ) @@ -25,6 +27,16 @@ func registerDebugEndpoints() error { return err } + if err := RegisterEndpoint(Endpoint{ + Path: "ready", + Read: PermitAnyone, + ActionFunc: ready, + Name: "Ready", + Description: "Check if Portmaster has completed starting and is ready.", + }); err != nil { + return err + } + if err := RegisterEndpoint(Endpoint{ Path: "debug/stack", Read: PermitAnyone, @@ -118,9 +130,22 @@ You can easily view this data in your browser with this command (with Go install // ping responds with pong. func ping(ar *Request) (msg string, err error) { + // TODO: Remove upgrade to "ready" when all UI components have transitioned. + if modules.IsStarting() || modules.IsShuttingDown() { + return "", ErrorWithStatus(errors.New("portmaster is not ready"), http.StatusTooEarly) + } + return "Pong.", nil } +// ready checks if Portmaster has completed starting. +func ready(ar *Request) (msg string, err error) { + if modules.IsStarting() || modules.IsShuttingDown() { + return "", ErrorWithStatus(errors.New("portmaster is not ready"), http.StatusTooEarly) + } + return "Portmaster is ready.", nil +} + // getStack returns the current goroutine stack. func getStack(_ *Request) (data []byte, err error) { buf := &bytes.Buffer{} diff --git a/modules/start.go b/modules/start.go index d73da5e..74730f2 100644 --- a/modules/start.go +++ b/modules/start.go @@ -24,6 +24,11 @@ func SetGlobalPrepFn(fn func() error) { } } +// IsStarting returns whether the initial global start is still in progress. +func IsStarting() bool { + return !initialStartCompleted.IsSet() +} + // Start starts all modules in the correct order. In case of an error, it will automatically shutdown again. func Start() error { if !modulesLocked.SetToIf(false, true) { From e35d3204987e0031ceb54b56c2b1cb7d30b36e9c Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 23 Apr 2024 10:49:16 +0200 Subject: [PATCH 3/3] Improve ready API error message --- api/endpoints_debug.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/endpoints_debug.go b/api/endpoints_debug.go index 2157b70..9491104 100644 --- a/api/endpoints_debug.go +++ b/api/endpoints_debug.go @@ -132,7 +132,7 @@ You can easily view this data in your browser with this command (with Go install func ping(ar *Request) (msg string, err error) { // TODO: Remove upgrade to "ready" when all UI components have transitioned. if modules.IsStarting() || modules.IsShuttingDown() { - return "", ErrorWithStatus(errors.New("portmaster is not ready"), http.StatusTooEarly) + return "", ErrorWithStatus(errors.New("portmaster is not ready, reload (F5) to try again"), http.StatusTooEarly) } return "Pong.", nil @@ -141,7 +141,7 @@ func ping(ar *Request) (msg string, err error) { // ready checks if Portmaster has completed starting. func ready(ar *Request) (msg string, err error) { if modules.IsStarting() || modules.IsShuttingDown() { - return "", ErrorWithStatus(errors.New("portmaster is not ready"), http.StatusTooEarly) + return "", ErrorWithStatus(errors.New("portmaster is not ready, reload (F5) to try again"), http.StatusTooEarly) } return "Portmaster is ready.", nil }