ipn/localapi: do not break client on event marshalling errors (#16503)

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 <claus@tailscale.com>
This commit is contained in:
Claus Lensbøl
2025-07-10 03:04:29 -04:00
committed by GitHub
parent 6a0fad1e10
commit fbc4c34cf7

View File

@@ -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)
}