Augment IsOfflineError(err) so that it detects if the hishtory server is down, and will then treat all API errors as offline errors

This commit is contained in:
David Dworken
2023-09-23 16:40:03 -07:00
parent bd03f90b0b
commit 8443292070
4 changed files with 35 additions and 2 deletions

View File

@@ -308,3 +308,7 @@ func (s *Server) feedbackHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Length", "0") w.Header().Set("Content-Length", "0")
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
} }
func (s *Server) pingHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("OK"))
}

View File

@@ -107,6 +107,7 @@ func (s *Server) Run(ctx context.Context, addr string) error {
mux.Handle("/api/v1/add-deletion-request", loggerMiddleware(s.addDeletionRequestHandler)) mux.Handle("/api/v1/add-deletion-request", loggerMiddleware(s.addDeletionRequestHandler))
mux.Handle("/api/v1/slsa-status", loggerMiddleware(s.slsaStatusHandler)) mux.Handle("/api/v1/slsa-status", loggerMiddleware(s.slsaStatusHandler))
mux.Handle("/api/v1/feedback", loggerMiddleware(s.feedbackHandler)) mux.Handle("/api/v1/feedback", loggerMiddleware(s.feedbackHandler))
mux.Handle("/api/v1/ping", loggerMiddleware(s.pingHandler))
mux.Handle("/healthcheck", loggerMiddleware(s.healthCheckHandler)) mux.Handle("/healthcheck", loggerMiddleware(s.healthCheckHandler))
mux.Handle("/internal/api/v1/usage-stats", loggerMiddleware(s.usageStatsHandler)) mux.Handle("/internal/api/v1/usage-stats", loggerMiddleware(s.usageStatsHandler))
mux.Handle("/internal/api/v1/stats", loggerMiddleware(s.statsHandler)) mux.Handle("/internal/api/v1/stats", loggerMiddleware(s.statsHandler))

View File

@@ -496,7 +496,7 @@ func IsOfflineError(err error) bool {
if err == nil { if err == nil {
return false return false
} }
return strings.Contains(err.Error(), "dial tcp: lookup api.hishtory.dev") || if strings.Contains(err.Error(), "dial tcp: lookup api.hishtory.dev") ||
strings.Contains(err.Error(), "connect: network is unreachable") || strings.Contains(err.Error(), "connect: network is unreachable") ||
strings.Contains(err.Error(), "read: connection reset by peer") || strings.Contains(err.Error(), "read: connection reset by peer") ||
strings.Contains(err.Error(), ": EOF") || strings.Contains(err.Error(), ": EOF") ||
@@ -505,7 +505,20 @@ func IsOfflineError(err error) bool {
strings.Contains(err.Error(), ": i/o timeout") || strings.Contains(err.Error(), ": i/o timeout") ||
strings.Contains(err.Error(), "connect: operation timed out") || strings.Contains(err.Error(), "connect: operation timed out") ||
strings.Contains(err.Error(), "net/http: TLS handshake timeout") || strings.Contains(err.Error(), "net/http: TLS handshake timeout") ||
strings.Contains(err.Error(), "connect: connection refused") strings.Contains(err.Error(), "connect: connection refused") {
return true
}
if !isHishtoryServerUp() {
// If the backend server is down, then treat all errors as offline errors
return true
}
// A truly unexpected error, bubble this up
return false
}
func isHishtoryServerUp() bool {
_, err := ApiGet("/api/v1/ping")
return err == nil
} }
func normalizeEntryTimezone(entry data.HistoryEntry) data.HistoryEntry { func normalizeEntryTimezone(entry data.HistoryEntry) data.HistoryEntry {

View File

@@ -1,6 +1,7 @@
package lib package lib
import ( import (
"fmt"
"os" "os"
"path" "path"
"reflect" "reflect"
@@ -11,6 +12,7 @@ import (
"github.com/ddworken/hishtory/client/hctx" "github.com/ddworken/hishtory/client/hctx"
"github.com/ddworken/hishtory/shared" "github.com/ddworken/hishtory/shared"
"github.com/ddworken/hishtory/shared/testutils" "github.com/ddworken/hishtory/shared/testutils"
"github.com/stretchr/testify/require"
) )
func TestSetup(t *testing.T) { func TestSetup(t *testing.T) {
@@ -355,3 +357,16 @@ func TestSplitEscaped(t *testing.T) {
} }
} }
} }
func TestAugmentedIsOfflineError(t *testing.T) {
defer testutils.BackupAndRestoreEnv("HISHTORY_SIMULATE_NETWORK_ERROR")()
// By default, when the hishtory server is up, then IsOfflineError checks the error msg
require.True(t, isHishtoryServerUp())
require.False(t, IsOfflineError(fmt.Errorf("unchecked error type")))
// When the hishtory server is down, then all error messages are treated as being due to offline errors
os.Setenv("HISHTORY_SIMULATE_NETWORK_ERROR", "1")
require.False(t, isHishtoryServerUp())
require.True(t, IsOfflineError(fmt.Errorf("unchecked error type")))
}