Prevent loop if there is an error in GetNotificationCount (#19799)

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>
This commit is contained in:
zeripath 2022-05-25 01:51:53 +01:00 committed by GitHub
parent b24db66a5f
commit 93ab90743d
Signed by: GitHub
GPG Key ID: 4AEE18F83AFDEB23

@ -5,6 +5,7 @@
package user package user
import ( import (
goctx "context"
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
@ -14,6 +15,7 @@ import (
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/structs"
) )
@ -36,7 +38,9 @@ func GetNotificationCount(c *context.Context) {
c.Data["NotificationUnreadCount"] = func() int64 { c.Data["NotificationUnreadCount"] = func() int64 {
count, err := models.GetNotificationCount(c, c.Doer, models.NotificationStatusUnread) count, err := models.GetNotificationCount(c, c.Doer, models.NotificationStatusUnread)
if err != nil { 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 return -1
} }