package webui import ( "fmt" "log/slog" "runtime/debug" "time" ) func goRecoverLoop(name string, restartDelay time.Duration, fn func()) { go func() { for { if !runRecoverable(name, fn) { return } if restartDelay > 0 { time.Sleep(restartDelay) } } }() } func goRecoverOnce(name string, fn func()) { go func() { _ = runRecoverable(name, fn) }() } func runRecoverable(name string, fn func()) (panicked bool) { defer func() { if rec := recover(); rec != nil { panicked = true slog.Error("recovered panic", "component", name, "panic", fmt.Sprint(rec), "stack", string(debug.Stack()), ) } }() fn() return false }