diff --git a/services/notify/notify.go b/services/notify/notify.go index b61588a0639..02c8c01a459 100644 --- a/services/notify/notify.go +++ b/services/notify/notify.go @@ -19,6 +19,12 @@ import ( var notifiers []Notifier +func recoverPanic() { + if err := recover(); err != nil { + log.Error("PANIC while notifying: %v\n%s", err, log.Stack(2)) + } +} + // RegisterNotifier providers method to receive notify messages func RegisterNotifier(notifier Notifier) { go notifier.Run() @@ -27,6 +33,8 @@ func RegisterNotifier(notifier Notifier) { // NewWikiPage notifies creating new wiki pages to notifiers func NewWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page, comment string) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.NewWikiPage(ctx, doer, repo, page, comment) } @@ -34,6 +42,8 @@ func NewWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Re // EditWikiPage notifies editing or renaming wiki pages to notifiers func EditWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page, comment string) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.EditWikiPage(ctx, doer, repo, page, comment) } @@ -41,6 +51,8 @@ func EditWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.R // DeleteWikiPage notifies deleting wiki pages to notifiers func DeleteWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, page string) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.DeleteWikiPage(ctx, doer, repo, page) } @@ -61,6 +73,8 @@ func shouldSendCommentChangeNotification(ctx context.Context, comment *issues_mo func CreateIssueComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, issue *issues_model.Issue, comment *issues_model.Comment, mentions []*user_model.User, ) { + defer recoverPanic() + if !shouldSendCommentChangeNotification(ctx, comment) { return } @@ -72,6 +86,8 @@ func CreateIssueComment(ctx context.Context, doer *user_model.User, repo *repo_m // NewIssue notifies new issue to notifiers func NewIssue(ctx context.Context, issue *issues_model.Issue, mentions []*user_model.User) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.NewIssue(ctx, issue, mentions) } @@ -79,6 +95,8 @@ func NewIssue(ctx context.Context, issue *issues_model.Issue, mentions []*user_m // IssueChangeStatus notifies close or reopen issue to notifiers func IssueChangeStatus(ctx context.Context, doer *user_model.User, commitID string, issue *issues_model.Issue, actionComment *issues_model.Comment, closeOrReopen bool) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.IssueChangeStatus(ctx, doer, commitID, issue, actionComment, closeOrReopen) } @@ -86,6 +104,8 @@ func IssueChangeStatus(ctx context.Context, doer *user_model.User, commitID stri // DeleteIssue notify when some issue deleted func DeleteIssue(ctx context.Context, doer *user_model.User, issue *issues_model.Issue) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.DeleteIssue(ctx, doer, issue) } @@ -93,6 +113,8 @@ func DeleteIssue(ctx context.Context, doer *user_model.User, issue *issues_model // MergePullRequest notifies merge pull request to notifiers func MergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.MergePullRequest(ctx, doer, pr) } @@ -100,6 +122,8 @@ func MergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_mod // AutoMergePullRequest notifies merge pull request to notifiers func AutoMergePullRequest(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.AutoMergePullRequest(ctx, doer, pr) } @@ -107,6 +131,8 @@ func AutoMergePullRequest(ctx context.Context, doer *user_model.User, pr *issues // NewPullRequest notifies new pull request to notifiers func NewPullRequest(ctx context.Context, pr *issues_model.PullRequest, mentions []*user_model.User) { + defer recoverPanic() + if err := pr.LoadIssue(ctx); err != nil { log.Error("LoadIssue failed: %v", err) return @@ -121,6 +147,8 @@ func NewPullRequest(ctx context.Context, pr *issues_model.PullRequest, mentions // PullRequestSynchronized notifies Synchronized pull request func PullRequestSynchronized(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, before, after string) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.PullRequestSynchronized(ctx, doer, pr, before, after) } @@ -128,6 +156,8 @@ func PullRequestSynchronized(ctx context.Context, doer *user_model.User, pr *iss // PullRequestReview notifies new pull request review func PullRequestReview(ctx context.Context, pr *issues_model.PullRequest, review *issues_model.Review, comment *issues_model.Comment, mentions []*user_model.User) { + defer recoverPanic() + if err := review.LoadReviewer(ctx); err != nil { log.Error("LoadReviewer failed: %v", err) return @@ -139,6 +169,8 @@ func PullRequestReview(ctx context.Context, pr *issues_model.PullRequest, review // PullRequestCodeComment notifies new pull request code comment func PullRequestCodeComment(ctx context.Context, pr *issues_model.PullRequest, comment *issues_model.Comment, mentions []*user_model.User) { + defer recoverPanic() + if err := comment.LoadPoster(ctx); err != nil { log.Error("LoadPoster: %v", err) return @@ -150,6 +182,8 @@ func PullRequestCodeComment(ctx context.Context, pr *issues_model.PullRequest, c // PullRequestChangeTargetBranch notifies when a pull request's target branch was changed func PullRequestChangeTargetBranch(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, oldBranch string) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.PullRequestChangeTargetBranch(ctx, doer, pr, oldBranch) } @@ -157,6 +191,8 @@ func PullRequestChangeTargetBranch(ctx context.Context, doer *user_model.User, p // PullRequestPushCommits notifies when push commits to pull request's head branch func PullRequestPushCommits(ctx context.Context, doer *user_model.User, pr *issues_model.PullRequest, comment *issues_model.Comment) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.PullRequestPushCommits(ctx, doer, pr, comment) } @@ -164,6 +200,8 @@ func PullRequestPushCommits(ctx context.Context, doer *user_model.User, pr *issu // PullReviewDismiss notifies when a review was dismissed by repo admin func PullReviewDismiss(ctx context.Context, doer *user_model.User, review *issues_model.Review, comment *issues_model.Comment) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.PullReviewDismiss(ctx, doer, review, comment) } @@ -171,6 +209,8 @@ func PullReviewDismiss(ctx context.Context, doer *user_model.User, review *issue // UpdateComment notifies update comment to notifiers func UpdateComment(ctx context.Context, doer *user_model.User, c *issues_model.Comment, oldContent string) { + defer recoverPanic() + if !shouldSendCommentChangeNotification(ctx, c) { return } @@ -182,6 +222,8 @@ func UpdateComment(ctx context.Context, doer *user_model.User, c *issues_model.C // DeleteComment notifies delete comment to notifiers func DeleteComment(ctx context.Context, doer *user_model.User, c *issues_model.Comment) { + defer recoverPanic() + if !shouldSendCommentChangeNotification(ctx, c) { return } @@ -193,6 +235,8 @@ func DeleteComment(ctx context.Context, doer *user_model.User, c *issues_model.C // NewRelease notifies new release to notifiers func NewRelease(ctx context.Context, rel *repo_model.Release) { + defer recoverPanic() + if err := rel.LoadAttributes(ctx); err != nil { log.Error("LoadPublisher: %v", err) return @@ -204,6 +248,8 @@ func NewRelease(ctx context.Context, rel *repo_model.Release) { // UpdateRelease notifies update release to notifiers func UpdateRelease(ctx context.Context, doer *user_model.User, rel *repo_model.Release) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.UpdateRelease(ctx, doer, rel) } @@ -211,6 +257,8 @@ func UpdateRelease(ctx context.Context, doer *user_model.User, rel *repo_model.R // DeleteRelease notifies delete release to notifiers func DeleteRelease(ctx context.Context, doer *user_model.User, rel *repo_model.Release) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.DeleteRelease(ctx, doer, rel) } @@ -218,6 +266,8 @@ func DeleteRelease(ctx context.Context, doer *user_model.User, rel *repo_model.R // IssueChangeMilestone notifies change milestone to notifiers func IssueChangeMilestone(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldMilestoneID int64) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.IssueChangeMilestone(ctx, doer, issue, oldMilestoneID) } @@ -225,6 +275,8 @@ func IssueChangeMilestone(ctx context.Context, doer *user_model.User, issue *iss // IssueChangeContent notifies change content to notifiers func IssueChangeContent(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldContent string) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.IssueChangeContent(ctx, doer, issue, oldContent) } @@ -232,6 +284,8 @@ func IssueChangeContent(ctx context.Context, doer *user_model.User, issue *issue // IssueChangeAssignee notifies change content to notifiers func IssueChangeAssignee(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.IssueChangeAssignee(ctx, doer, issue, assignee, removed, comment) } @@ -239,6 +293,8 @@ func IssueChangeAssignee(ctx context.Context, doer *user_model.User, issue *issu // PullRequestReviewRequest notifies Request Review change func PullRequestReviewRequest(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.PullRequestReviewRequest(ctx, doer, issue, reviewer, isRequest, comment) } @@ -246,6 +302,8 @@ func PullRequestReviewRequest(ctx context.Context, doer *user_model.User, issue // IssueClearLabels notifies clear labels to notifiers func IssueClearLabels(ctx context.Context, doer *user_model.User, issue *issues_model.Issue) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.IssueClearLabels(ctx, doer, issue) } @@ -253,6 +311,8 @@ func IssueClearLabels(ctx context.Context, doer *user_model.User, issue *issues_ // IssueChangeTitle notifies change title to notifiers func IssueChangeTitle(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldTitle string) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.IssueChangeTitle(ctx, doer, issue, oldTitle) } @@ -260,6 +320,8 @@ func IssueChangeTitle(ctx context.Context, doer *user_model.User, issue *issues_ // IssueChangeRef notifies change reference to notifiers func IssueChangeRef(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldRef string) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.IssueChangeRef(ctx, doer, issue, oldRef) } @@ -269,6 +331,8 @@ func IssueChangeRef(ctx context.Context, doer *user_model.User, issue *issues_mo func IssueChangeLabels(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, addedLabels, removedLabels []*issues_model.Label, ) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.IssueChangeLabels(ctx, doer, issue, addedLabels, removedLabels) } @@ -276,6 +340,8 @@ func IssueChangeLabels(ctx context.Context, doer *user_model.User, issue *issues // CreateRepository notifies create repository to notifiers func CreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.CreateRepository(ctx, doer, u, repo) } @@ -283,6 +349,8 @@ func CreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_ // AdoptRepository notifies the adoption of a repository to notifiers func AdoptRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.AdoptRepository(ctx, doer, u, repo) } @@ -290,6 +358,8 @@ func AdoptRepository(ctx context.Context, doer, u *user_model.User, repo *repo_m // MigrateRepository notifies create repository to notifiers func MigrateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_model.Repository) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.MigrateRepository(ctx, doer, u, repo) } @@ -297,6 +367,8 @@ func MigrateRepository(ctx context.Context, doer, u *user_model.User, repo *repo // TransferRepository notifies create repository to notifiers func TransferRepository(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, oldOwnerName string) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.TransferRepository(ctx, doer, repo, oldOwnerName) } @@ -304,6 +376,8 @@ func TransferRepository(ctx context.Context, doer *user_model.User, repo *repo_m // DeleteRepository notifies delete repository to notifiers func DeleteRepository(ctx context.Context, doer *user_model.User, repo *repo_model.Repository) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.DeleteRepository(ctx, doer, repo) } @@ -311,6 +385,8 @@ func DeleteRepository(ctx context.Context, doer *user_model.User, repo *repo_mod // ForkRepository notifies fork repository to notifiers func ForkRepository(ctx context.Context, doer *user_model.User, oldRepo, repo *repo_model.Repository) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.ForkRepository(ctx, doer, oldRepo, repo) } @@ -318,6 +394,8 @@ func ForkRepository(ctx context.Context, doer *user_model.User, oldRepo, repo *r // RenameRepository notifies repository renamed func RenameRepository(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, oldName string) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.RenameRepository(ctx, doer, repo, oldName) } @@ -325,6 +403,8 @@ func RenameRepository(ctx context.Context, doer *user_model.User, repo *repo_mod // PushCommits notifies commits pushed to notifiers func PushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.PushCommits(ctx, pusher, repo, opts, commits) } @@ -332,6 +412,8 @@ func PushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model. // CreateRef notifies branch or tag creation to notifiers func CreateRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName, refID string) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.CreateRef(ctx, pusher, repo, refFullName, refID) } @@ -339,6 +421,8 @@ func CreateRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Re // DeleteRef notifies branch or tag deletion to notifiers func DeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.DeleteRef(ctx, pusher, repo, refFullName) } @@ -346,6 +430,8 @@ func DeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Re // SyncPushCommits notifies commits pushed to notifiers func SyncPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.SyncPushCommits(ctx, pusher, repo, opts, commits) } @@ -353,6 +439,8 @@ func SyncPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_mo // SyncCreateRef notifies branch or tag creation to notifiers func SyncCreateRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName, refID string) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.SyncCreateRef(ctx, pusher, repo, refFullName, refID) } @@ -360,6 +448,8 @@ func SyncCreateRef(ctx context.Context, pusher *user_model.User, repo *repo_mode // SyncDeleteRef notifies branch or tag deletion to notifiers func SyncDeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, refFullName git.RefName) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.SyncDeleteRef(ctx, pusher, repo, refFullName) } @@ -367,6 +457,8 @@ func SyncDeleteRef(ctx context.Context, pusher *user_model.User, repo *repo_mode // RepoPendingTransfer notifies creation of pending transfer to notifiers func RepoPendingTransfer(ctx context.Context, doer, newOwner *user_model.User, repo *repo_model.Repository) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.RepoPendingTransfer(ctx, doer, newOwner, repo) } @@ -374,6 +466,8 @@ func RepoPendingTransfer(ctx context.Context, doer, newOwner *user_model.User, r // PackageCreate notifies creation of a package to notifiers func PackageCreate(ctx context.Context, doer *user_model.User, pd *packages_model.PackageDescriptor) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.PackageCreate(ctx, doer, pd) } @@ -381,6 +475,8 @@ func PackageCreate(ctx context.Context, doer *user_model.User, pd *packages_mode // PackageDelete notifies deletion of a package to notifiers func PackageDelete(ctx context.Context, doer *user_model.User, pd *packages_model.PackageDescriptor) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.PackageDelete(ctx, doer, pd) } @@ -388,12 +484,16 @@ func PackageDelete(ctx context.Context, doer *user_model.User, pd *packages_mode // ChangeDefaultBranch notifies change default branch to notifiers func ChangeDefaultBranch(ctx context.Context, repo *repo_model.Repository) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.ChangeDefaultBranch(ctx, repo) } } func CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, commit *repository.PushCommit, sender *user_model.User, status *git_model.CommitStatus) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.CreateCommitStatus(ctx, repo, commit, sender, status) } @@ -403,6 +503,8 @@ func CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, commit // Prefer the helpers in services/actions/notify.go over calling this directly; // unless you are sure the caller has already resolved the correct sender and paired notifications. func WorkflowRunStatusUpdate(ctx context.Context, repo *repo_model.Repository, sender *user_model.User, run *actions_model.ActionRun) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.WorkflowRunStatusUpdate(ctx, repo, sender, run) } @@ -412,6 +514,8 @@ func WorkflowRunStatusUpdate(ctx context.Context, repo *repo_model.Repository, s // Prefer the helpers in services/actions/notify.go over calling this directly; // unless you are sure the caller has already resolved the correct sender and paired notifications. func WorkflowJobStatusUpdate(ctx context.Context, repo *repo_model.Repository, sender *user_model.User, job *actions_model.ActionRunJob, task *actions_model.ActionTask) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.WorkflowJobStatusUpdate(ctx, repo, sender, job, task) } @@ -419,6 +523,8 @@ func WorkflowJobStatusUpdate(ctx context.Context, repo *repo_model.Repository, s // Callers must invoke this after any DB write affecting the user's unread count. func NotificationCountChange(ctx context.Context, userID int64) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.NotificationCountChange(ctx, userID) } @@ -426,6 +532,8 @@ func NotificationCountChange(ctx context.Context, userID int64) { // Callers must invoke this after any stopwatch start/stop/cancel so the user's connected tabs refresh. func StopwatchChanged(ctx context.Context, user *user_model.User) { + defer recoverPanic() + for _, notifier := range notifiers { notifier.StopwatchChanged(ctx, user) }