From fbc4c34cf7377f4ddb1d95163085e2b27c845018 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus=20Lensb=C3=B8l?= Date: Thu, 10 Jul 2025 03:04:29 -0400 Subject: [PATCH] ipn/localapi: do not break client on event marshalling errors (#16503) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Errors were mashalled without the correct newlines. Also, they could generally be mashalled with more data, so an intermediate was introduced to make them slightly nicer to look at. Updates #15160 Signed-off-by: Claus Lensbøl --- ipn/localapi/localapi.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/ipn/localapi/localapi.go b/ipn/localapi/localapi.go index 60ed89b3b..cd59c54e0 100644 --- a/ipn/localapi/localapi.go +++ b/ipn/localapi/localapi.go @@ -919,6 +919,11 @@ func (h *Handler) serveDebugPortmap(w http.ResponseWriter, r *http.Request) { } } +// EventError provides the JSON encoding of internal errors from event processing. +type EventError struct { + Error string +} + // serveDebugBusEvents taps into the tailscaled/utils/eventbus and streams // events to the client. func (h *Handler) serveDebugBusEvents(w http.ResponseWriter, r *http.Request) { @@ -971,7 +976,16 @@ func (h *Handler) serveDebugBusEvents(w http.ResponseWriter, r *http.Request) { } if msg, err := json.Marshal(data); err != nil { - fmt.Fprintf(w, `{"Event":"[ERROR] failed to marshal JSON for %T"}\n`, event.Event) + data.Event = EventError{Error: fmt.Sprintf( + "failed to marshal JSON for %T", event.Event, + )} + if errMsg, err := json.Marshal(data); err != nil { + fmt.Fprintf(w, + `{"Count": %d, "Event":"[ERROR] failed to marshal JSON for %T\n"}`, + i, event.Event) + } else { + w.Write(errMsg) + } } else { w.Write(msg) }