From 08c9196545890f8927f1e9f1905ec72acd75ed21 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 6 Feb 2026 07:16:08 +0000 Subject: [PATCH] all: fix errcheck lint issues (batch 2) Check return values from: - JSON encoder writes in HTTP handlers - http.Serve calls in tailsql (with gosec nolint for timeout) - cobra MarkFlagRequired calls - middleware additions - http response writes Co-Authored-By: Claude Opus 4.5 --- cmd/headscale/cli/mockoidc.go | 2 +- cmd/headscale/cli/nodes.go | 4 ++-- cmd/headscale/cli/users.go | 3 ++- hscontrol/app.go | 2 +- hscontrol/db/db.go | 2 +- hscontrol/debug.go | 6 +++--- hscontrol/handlers.go | 17 ++++++++++++++--- hscontrol/platform_config.go | 4 ++-- hscontrol/tailsql.go | 14 +++++++++----- 9 files changed, 35 insertions(+), 19 deletions(-) diff --git a/cmd/headscale/cli/mockoidc.go b/cmd/headscale/cli/mockoidc.go index 6b104bf8..e7c42dc6 100644 --- a/cmd/headscale/cli/mockoidc.go +++ b/cmd/headscale/cli/mockoidc.go @@ -142,7 +142,7 @@ func getMockOIDC(clientID string, clientSecret string, users []mockoidc.MockUser ErrorQueue: &mockoidc.ErrorQueue{}, } - mock.AddMiddleware(func(h http.Handler) http.Handler { + _ = mock.AddMiddleware(func(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { log.Info().Msgf("request: %+v", r) h.ServeHTTP(w, r) diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index e138b42b..b5192318 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -82,12 +82,12 @@ func init() { nodeCmd.AddCommand(deleteNodeCmd) tagCmd.Flags().Uint64P("identifier", "i", 0, "Node identifier (ID)") - tagCmd.MarkFlagRequired("identifier") + _ = tagCmd.MarkFlagRequired("identifier") tagCmd.Flags().StringSliceP("tags", "t", []string{}, "List of tags to add to the node") nodeCmd.AddCommand(tagCmd) approveRoutesCmd.Flags().Uint64P("identifier", "i", 0, "Node identifier (ID)") - approveRoutesCmd.MarkFlagRequired("identifier") + _ = approveRoutesCmd.MarkFlagRequired("identifier") approveRoutesCmd.Flags().StringSliceP("routes", "r", []string{}, `List of routes that will be approved (comma-separated, e.g. "10.0.0.0/8,192.168.0.0/24" or empty string to remove all approved routes)`) nodeCmd.AddCommand(approveRoutesCmd) diff --git a/cmd/headscale/cli/users.go b/cmd/headscale/cli/users.go index 60989000..7668bac8 100644 --- a/cmd/headscale/cli/users.go +++ b/cmd/headscale/cli/users.go @@ -52,7 +52,8 @@ func init() { userCmd.AddCommand(renameUserCmd) usernameAndIDFlag(renameUserCmd) renameUserCmd.Flags().StringP("new-name", "r", "", "New username") - renameNodeCmd.MarkFlagRequired("new-name") + + _ = renameNodeCmd.MarkFlagRequired("new-name") } var errMissingParameter = errors.New("missing parameters") diff --git a/hscontrol/app.go b/hscontrol/app.go index a30e09d0..9eb80e5a 100644 --- a/hscontrol/app.go +++ b/hscontrol/app.go @@ -799,7 +799,7 @@ func (h *Headscale) Serve() error { tailsqlContext = context.Background() - go runTailSQLService(ctx, util.TSLogfWrapper(), tailsqlStateDir, h.cfg.Database.Sqlite.Path) + go runTailSQLService(ctx, util.TSLogfWrapper(), tailsqlStateDir, h.cfg.Database.Sqlite.Path) //nolint:errcheck } // Handle common process-killing signals so we can gracefully shut down: diff --git a/hscontrol/db/db.go b/hscontrol/db/db.go index 30fa2ea9..ca8daecb 100644 --- a/hscontrol/db/db.go +++ b/hscontrol/db/db.go @@ -1050,7 +1050,7 @@ func (hsdb *HSDatabase) Close() error { } if hsdb.cfg.Database.Type == types.DatabaseSqlite && hsdb.cfg.Database.Sqlite.WriteAheadLog { - db.Exec("VACUUM") + db.Exec("VACUUM") //nolint:errcheck,noctx } return db.Close() diff --git a/hscontrol/debug.go b/hscontrol/debug.go index 4fdcac11..4bafc565 100644 --- a/hscontrol/debug.go +++ b/hscontrol/debug.go @@ -34,14 +34,14 @@ func (h *Headscale) debugHTTPServer() *http.Server { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - w.Write(overviewJSON) + _, _ = w.Write(overviewJSON) } else { // Default to text/plain for backward compatibility overview := h.state.DebugOverview() w.Header().Set("Content-Type", "text/plain") w.WriteHeader(http.StatusOK) - w.Write([]byte(overview)) + _, _ = w.Write([]byte(overview)) } })) @@ -57,7 +57,7 @@ func (h *Headscale) debugHTTPServer() *http.Server { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - w.Write(configJSON) + _, _ = w.Write(configJSON) })) // Policy endpoint diff --git a/hscontrol/handlers.go b/hscontrol/handlers.go index 7516f8c7..79d22740 100644 --- a/hscontrol/handlers.go +++ b/hscontrol/handlers.go @@ -155,7 +155,11 @@ func (h *Headscale) KeyHandler( } writer.Header().Set("Content-Type", "application/json") - json.NewEncoder(writer).Encode(resp) + + err := json.NewEncoder(writer).Encode(resp) + if err != nil { + log.Error().Err(err).Msg("failed to encode public key response") + } return } @@ -180,7 +184,10 @@ func (h *Headscale) HealthHandler( res.Status = "fail" } - json.NewEncoder(writer).Encode(res) + encErr := json.NewEncoder(writer).Encode(res) + if encErr != nil { + log.Error().Err(encErr).Msg("failed to encode health response") + } } err := h.state.PingDB(req.Context()) @@ -269,7 +276,11 @@ func (a *AuthProviderWeb) RegisterHandler( writer.Header().Set("Content-Type", "text/html; charset=utf-8") writer.WriteHeader(http.StatusOK) - writer.Write([]byte(templates.RegisterWeb(registrationId).Render())) + + _, err = writer.Write([]byte(templates.RegisterWeb(registrationId).Render())) + if err != nil { + log.Error().Err(err).Msg("failed to write register response") + } } func FaviconHandler(writer http.ResponseWriter, req *http.Request) { diff --git a/hscontrol/platform_config.go b/hscontrol/platform_config.go index 2b88e2da..54d57b1c 100644 --- a/hscontrol/platform_config.go +++ b/hscontrol/platform_config.go @@ -19,7 +19,7 @@ func (h *Headscale) WindowsConfigMessage( ) { writer.Header().Set("Content-Type", "text/html; charset=utf-8") writer.WriteHeader(http.StatusOK) - writer.Write([]byte(templates.Windows(h.cfg.ServerURL).Render())) + _, _ = writer.Write([]byte(templates.Windows(h.cfg.ServerURL).Render())) } // AppleConfigMessage shows a simple message in the browser to point the user to the iOS/MacOS profile and instructions for how to install it. @@ -29,7 +29,7 @@ func (h *Headscale) AppleConfigMessage( ) { writer.Header().Set("Content-Type", "text/html; charset=utf-8") writer.WriteHeader(http.StatusOK) - writer.Write([]byte(templates.Apple(h.cfg.ServerURL).Render())) + _, _ = writer.Write([]byte(templates.Apple(h.cfg.ServerURL).Render())) } func (h *Headscale) ApplePlatformConfig( diff --git a/hscontrol/tailsql.go b/hscontrol/tailsql.go index 8b0c7119..e891e30f 100644 --- a/hscontrol/tailsql.go +++ b/hscontrol/tailsql.go @@ -78,10 +78,12 @@ func runTailSQLService(ctx context.Context, logf logger.Logf, stateDir, dbPath s base := "https://" + certDomains[0] - go http.Serve(lst, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - target := base + r.RequestURI - http.Redirect(w, r, target, http.StatusPermanentRedirect) - })) + go func() { + _ = http.Serve(lst, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { //nolint:gosec + target := base + r.RequestURI + http.Redirect(w, r, target, http.StatusPermanentRedirect) + })) + }() // log.Printf("Redirecting HTTP to HTTPS at %q", base) // For the real service, start a separate listener. @@ -99,7 +101,9 @@ func runTailSQLService(ctx context.Context, logf logger.Logf, stateDir, dbPath s mux := tsql.NewMux() tsweb.Debugger(mux) - go http.Serve(lst, mux) + go func() { + _ = http.Serve(lst, mux) //nolint:gosec + }() logf("TailSQL started") <-ctx.Done()