If the context is cancelled `.NotificationUnreadCount` in a template can cause an infinite loop with `ctx.ServerError()` being called, which creates a template that then calls `.NotificationUnreadCount` calling `GetNotificationCount()` with the cancelled context resulting in an error that calls `ctx.ServerError`... and so on... This PR simply stops calling `ctx.ServerError` in the error handler code for `.NotificationUnreadCount` as we have already started rendering and so it is too late to call `ctx.ServerError`. Additionally we skip logging the error if it's a context cancelled error. Fix #19793 Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: techknowlogick <techknowlogick@gitea.io>tags/v1.18.0-dev
@@ -5,6 +5,7 @@ | |||
package user | |||
import ( | |||
goctx "context" | |||
"errors" | |||
"fmt" | |||
"net/http" | |||
@@ -14,6 +15,7 @@ import ( | |||
"code.gitea.io/gitea/models" | |||
"code.gitea.io/gitea/modules/base" | |||
"code.gitea.io/gitea/modules/context" | |||
"code.gitea.io/gitea/modules/log" | |||
"code.gitea.io/gitea/modules/setting" | |||
"code.gitea.io/gitea/modules/structs" | |||
) | |||
@@ -36,7 +38,9 @@ func GetNotificationCount(c *context.Context) { | |||
c.Data["NotificationUnreadCount"] = func() int64 { | |||
count, err := models.GetNotificationCount(c, c.Doer, models.NotificationStatusUnread) | |||
if err != nil { | |||
c.ServerError("GetNotificationCount", err) | |||
if err != goctx.Canceled { | |||
log.Error("Unable to GetNotificationCount for user:%-v: %v", c.Doer, err) | |||
} | |||
return -1 | |||
} | |||