Просмотр исходного кода

fix(web): recover panicking cron jobs instead of crashing the panel (#5363)

The scheduler was created without a panic recovery wrapper, so a panic in any
scheduled job (traffic write, IP check, etc.) propagated up and could take down
the whole panel process. Wrap jobs with cron.Recover so a panic is logged and
the scheduler keeps running.
n0ctal 1 день назад
Родитель
Сommit
bedbe04bf1
1 измененных файлов с 9 добавлено и 1 удалено
  1. 9 1
      internal/web/web.go

+ 9 - 1
internal/web/web.go

@@ -53,6 +53,12 @@ var distFS embed.FS
 
 var startTime = time.Now()
 
+// cronPanicLogger adapts the package logger to cron's Printf-style logger so a
+// panicking scheduled job is recovered and logged instead of crashing the panel.
+type cronPanicLogger struct{}
+
+func (cronPanicLogger) Printf(format string, args ...any) { logger.Errorf(format, args...) }
+
 // wrapDistFS adapts the embedded `dist/` directory so it can be mounted
 // as the panel's `/assets/` static route. Vite emits its bundled JS/CSS
 // under `dist/assets/`; serving the FS rooted at `dist/assets` makes
@@ -435,7 +441,9 @@ func (s *Server) start(restartXray bool, startTgBot bool) (err error) {
 	}
 	service.StartTrafficWriter()
 
-	s.cron = cron.New(cron.WithLocation(loc), cron.WithSeconds())
+	// cron.Recover wraps every job so a panic is logged and the scheduler keeps
+	// running, instead of the panic taking down the whole panel process.
+	s.cron = cron.New(cron.WithLocation(loc), cron.WithSeconds(), cron.WithChain(cron.Recover(cron.PrintfLogger(cronPanicLogger{}))))
 	s.cron.Start()
 
 	// Wire the inbound-runtime manager once so InboundService can route