From 026a4bb02d8ac0b0dd90eb8a89c25ae18abca34f Mon Sep 17 00:00:00 2001
From: Gusted <postmaster@gusted.xyz>
Date: Sun, 10 Dec 2023 16:57:16 +0100
Subject: [PATCH] [GITEA] Actually recover from a panic in cron task

- Backport #1911
- Currently there's code to recover gracefully from panics that happen
within the execution of cron tasks. However this recover code wasn't
being run, because `RunWithShutdownContext` also contains code to
recover from any panic and then gracefully shutdown Forgejo. Because
`RunWithShutdownContext` registers that code as last, that would get run
first which in this case is not behavior that we want.
- Move the recover code to inside the function, so that is run first
before `RunWithShutdownContext`'s recover code (which is now a noop).
- Resolves #1910

(cherry picked from commit 761e1c83414407b65e331c2eeb4348c47acf0fbb)
---
 services/cron/tasks.go | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/services/cron/tasks.go b/services/cron/tasks.go
index d2c3d1d812..f0956a97d8 100644
--- a/services/cron/tasks.go
+++ b/services/cron/tasks.go
@@ -84,13 +84,15 @@ func (t *Task) RunWithUser(doer *user_model.User, config Config) {
 	t.lock.Unlock()
 	defer func() {
 		taskStatusTable.Stop(t.Name)
-		if err := recover(); err != nil {
-			// Recover a panic within the
-			combinedErr := fmt.Errorf("%s\n%s", err, log.Stack(2))
-			log.Error("PANIC whilst running task: %s Value: %v", t.Name, combinedErr)
-		}
 	}()
 	graceful.GetManager().RunWithShutdownContext(func(baseCtx context.Context) {
+		defer func() {
+			if err := recover(); err != nil {
+				// Recover a panic within the execution of the task.
+				combinedErr := fmt.Errorf("%s\n%s", err, log.Stack(2))
+				log.Error("PANIC whilst running task: %s Value: %v", t.Name, combinedErr)
+			}
+		}()
 		// Store the time of this run, before the function is executed, so it
 		// matches the behavior of what the cron library does.
 		t.lock.Lock()