[MM-56757] Expand NotificationsLog to include websocket and email, adding much more varied logging across the entire process (#26273)
* [MM-56757] Expand NotificationsLog to include websocket and email, adding much more varied logging across the entire process * Rework the status/notify prop calls * Avoid some repetition in the logging calls * Fix one log * Wrap error --------- Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
2690e1322a
Коммит
893c44fe85
@@ -23,11 +23,19 @@ import (
|
||||
|
||||
func (a *App) canSendPushNotifications() bool {
|
||||
if !*a.Config().EmailSettings.SendPushNotifications {
|
||||
a.NotificationsLog().Debug("Push notifications are disabled - server config",
|
||||
mlog.String("status", model.StatusBlocked),
|
||||
mlog.String("reason", model.ReasonServerConfig),
|
||||
)
|
||||
return false
|
||||
}
|
||||
|
||||
pushServer := *a.Config().EmailSettings.PushNotificationServer
|
||||
if license := a.Srv().License(); pushServer == model.MHPNS && (license == nil || !*license.Features.MHPNS) {
|
||||
a.NotificationsLog().Info("Push notifications are disabled - license missing",
|
||||
mlog.String("status", model.StatusBlocked),
|
||||
mlog.String("reason", model.ReasonServerConfig),
|
||||
)
|
||||
mlog.Warn("Push notifications have been disabled. Update your license or go to System Console > Environment > Push Notification Server to use a different server")
|
||||
return false
|
||||
}
|
||||
@@ -89,12 +97,26 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea
|
||||
|
||||
pResult := <-pchan
|
||||
if pResult.NErr != nil {
|
||||
a.NotificationsLog().Error("Error fetching profiles",
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusServerError),
|
||||
mlog.String("reason", model.ReasonFetchError),
|
||||
mlog.Err(pResult.NErr),
|
||||
)
|
||||
return nil, pResult.NErr
|
||||
}
|
||||
profileMap := pResult.Data
|
||||
|
||||
cmnResult := <-cmnchan
|
||||
if cmnResult.NErr != nil {
|
||||
a.NotificationsLog().Error("Error fetching notify props",
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusServerError),
|
||||
mlog.String("reason", model.ReasonFetchError),
|
||||
mlog.Err(cmnResult.NErr),
|
||||
)
|
||||
return nil, cmnResult.NErr
|
||||
}
|
||||
channelMemberNotifyPropsMap := cmnResult.Data
|
||||
@@ -103,6 +125,13 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea
|
||||
if tchan != nil {
|
||||
tResult := <-tchan
|
||||
if tResult.NErr != nil {
|
||||
a.NotificationsLog().Error("Error fetching thread followers",
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusServerError),
|
||||
mlog.String("reason", model.ReasonFetchError),
|
||||
mlog.Err(tResult.NErr),
|
||||
)
|
||||
return nil, tResult.NErr
|
||||
}
|
||||
for _, v := range tResult.Data {
|
||||
@@ -114,11 +143,23 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea
|
||||
if gchan != nil {
|
||||
gResult := <-gchan
|
||||
if gResult.NErr != nil {
|
||||
a.NotificationsLog().Error("Error fetching group mentions",
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusServerError),
|
||||
mlog.String("reason", model.ReasonFetchError),
|
||||
mlog.Err(gResult.NErr),
|
||||
)
|
||||
return nil, gResult.NErr
|
||||
}
|
||||
groups = gResult.Data
|
||||
}
|
||||
|
||||
a.NotificationsLog().Trace("Successfully fetched all profiles",
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("post_id", post.Id),
|
||||
)
|
||||
|
||||
mentions, keywords := a.getExplicitMentionsAndKeywords(c, post, channel, profileMap, groups, channelMemberNotifyPropsMap, parentPostList)
|
||||
|
||||
var allActivityPushUserIds []string
|
||||
@@ -128,6 +169,13 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea
|
||||
group := groups[groupID]
|
||||
anyUsersMentionedByGroup, err := a.insertGroupMentions(sender.Id, group, channel, profileMap, mentions)
|
||||
if err != nil {
|
||||
a.NotificationsLog().Error("Failed to populate group mentions",
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusServerError),
|
||||
mlog.String("reason", model.ReasonFetchError),
|
||||
mlog.Err(err),
|
||||
)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -139,6 +187,13 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea
|
||||
go func() {
|
||||
_, err := a.sendOutOfChannelMentions(c, sender, post, channel, mentions.OtherPotentialMentions)
|
||||
if err != nil {
|
||||
a.NotificationsLog().Warn("Failed to send warning for out of channel mentions",
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusServerError),
|
||||
mlog.String("reason", model.ReasonServerError),
|
||||
mlog.Err(err),
|
||||
)
|
||||
c.Logger().Error("Failed to send warning for out of channel mentions", mlog.String("user_id", sender.Id), mlog.String("post_id", post.Id), mlog.Err(err))
|
||||
}
|
||||
}()
|
||||
@@ -270,6 +325,11 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea
|
||||
)
|
||||
}
|
||||
|
||||
a.NotificationsLog().Trace("Finished processing mentions",
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("post_id", post.Id),
|
||||
)
|
||||
|
||||
// Log the problems that might have occurred while auto following the thread
|
||||
for _, mac := range mentionAutofollowChans {
|
||||
if err := <-mac; err != nil {
|
||||
@@ -307,16 +367,37 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea
|
||||
}
|
||||
|
||||
if *a.Config().EmailSettings.SendEmailNotifications {
|
||||
a.NotificationsLog().Trace("Begin sending email notifications",
|
||||
mlog.String("type", model.TypeEmail),
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("post_id", post.Id),
|
||||
)
|
||||
emailRecipients := append(mentionedUsersList, notificationsForCRT.Email...)
|
||||
emailRecipients = model.RemoveDuplicateStrings(emailRecipients)
|
||||
|
||||
for _, id := range emailRecipients {
|
||||
if profileMap[id] == nil {
|
||||
a.NotificationsLog().Warn("Missing profile",
|
||||
mlog.String("type", model.TypeEmail),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusNotSent),
|
||||
mlog.String("reason", model.ReasonMissingProfile),
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("receiver_id", id),
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
//If email verification is required and user email is not verified don't send email.
|
||||
if *a.Config().EmailSettings.RequireEmailVerification && !profileMap[id].EmailVerified {
|
||||
a.NotificationsLog().Debug("Email not verified",
|
||||
mlog.String("type", model.TypeEmail),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusNotSent),
|
||||
mlog.String("reason", model.ReasonUserConfig),
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("receiver_id", id),
|
||||
)
|
||||
c.Logger().Debug("Skipped sending notification email, address not verified.", mlog.String("user_email", profileMap[id].Email), mlog.String("user_id", id))
|
||||
continue
|
||||
}
|
||||
@@ -327,14 +408,45 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea
|
||||
a.Log().Warn("Unable to get the sender user profile image.", mlog.String("user_id", sender.Id), mlog.Err(err))
|
||||
}
|
||||
if err := a.sendNotificationEmail(c, notification, profileMap[id], team, senderProfileImage); err != nil {
|
||||
a.NotificationsLog().Warn("Error sending email notification",
|
||||
mlog.String("type", model.TypeEmail),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusNotSent),
|
||||
mlog.String("reason", model.ReasonServerError),
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("receiver_id", id),
|
||||
mlog.Err(err),
|
||||
)
|
||||
c.Logger().Warn("Unable to send notification email.", mlog.Err(err))
|
||||
}
|
||||
} else {
|
||||
a.NotificationsLog().Debug("Email disallowed by user",
|
||||
mlog.String("type", model.TypeEmail),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusNotSent),
|
||||
mlog.String("reason", model.ReasonUserConfig),
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("receiver_id", id),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
a.NotificationsLog().Trace("Finished sending email notifications",
|
||||
mlog.String("type", model.TypeEmail),
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("post_id", post.Id),
|
||||
)
|
||||
}
|
||||
|
||||
// Check for channel-wide mentions in channels that have too many members for those to work
|
||||
if int64(len(profileMap)) > *a.Config().TeamSettings.MaxNotificationsPerChannel {
|
||||
a.NotificationsLog().Debug("Too many users to notify - will send ephemeral message",
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusNotSent),
|
||||
mlog.String("reason", model.ReasonServerConfig),
|
||||
)
|
||||
|
||||
T := i18n.GetUserTranslations(sender.Locale)
|
||||
|
||||
if mentions.HereMentioned {
|
||||
@@ -375,8 +487,32 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea
|
||||
}
|
||||
|
||||
if a.canSendPushNotifications() {
|
||||
a.NotificationsLog().Trace("Begin sending push notifications",
|
||||
mlog.String("type", model.TypePush),
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("post_id", post.Id),
|
||||
)
|
||||
|
||||
for _, id := range mentionedUsersList {
|
||||
if profileMap[id] == nil || notificationsForCRT.Push.Contains(id) {
|
||||
if profileMap[id] == nil {
|
||||
a.NotificationsLog().Warn("Missing profile",
|
||||
mlog.String("type", model.TypePush),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusNotSent),
|
||||
mlog.String("reason", model.ReasonMissingProfile),
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("receiver_id", id),
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
if notificationsForCRT.Push.Contains(id) {
|
||||
a.NotificationsLog().Trace("Skipped direct push notification - will send as CRT notification",
|
||||
mlog.String("type", model.TypePush),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusNotSent),
|
||||
mlog.String("sender_id", sender.Id),
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -388,7 +524,7 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea
|
||||
|
||||
isExplicitlyMentioned := mentions.Mentions[id] > GMMention
|
||||
isGM := channel.Type == model.ChannelTypeGroup
|
||||
if ShouldSendPushNotification(profileMap[id], channelMemberNotifyPropsMap[id], isExplicitlyMentioned, status, post, isGM) {
|
||||
if a.ShouldSendPushNotification(profileMap[id], channelMemberNotifyPropsMap[id], isExplicitlyMentioned, status, post, isGM) {
|
||||
mentionType := mentions.Mentions[id]
|
||||
|
||||
replyToThreadType := ""
|
||||
@@ -405,20 +541,29 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea
|
||||
mentionType == ChannelMention,
|
||||
replyToThreadType,
|
||||
)
|
||||
} else {
|
||||
// register that a notification was not sent
|
||||
a.NotificationsLog().Debug("Notification not sent",
|
||||
mlog.String("ackId", ""),
|
||||
mlog.String("type", model.PushTypeMessage),
|
||||
mlog.String("userId", id),
|
||||
mlog.String("postId", post.Id),
|
||||
mlog.String("status", model.PushNotSent),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
for _, id := range allActivityPushUserIds {
|
||||
if profileMap[id] == nil || notificationsForCRT.Push.Contains(id) {
|
||||
if profileMap[id] == nil {
|
||||
a.NotificationsLog().Warn("Missing profile",
|
||||
mlog.String("type", model.TypePush),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusNotSent),
|
||||
mlog.String("reason", model.ReasonMissingProfile),
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("receiver_id", id),
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
if notificationsForCRT.Push.Contains(id) {
|
||||
a.NotificationsLog().Trace("Skipped direct push notification - will send as CRT notification",
|
||||
mlog.String("type", model.TypePush),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusNotSent),
|
||||
mlog.String("sender_id", sender.Id),
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -430,7 +575,7 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea
|
||||
}
|
||||
|
||||
isGM := channel.Type == model.ChannelTypeGroup
|
||||
if ShouldSendPushNotification(profileMap[id], channelMemberNotifyPropsMap[id], false, status, post, isGM) {
|
||||
if a.ShouldSendPushNotification(profileMap[id], channelMemberNotifyPropsMap[id], false, status, post, isGM) {
|
||||
a.sendPushNotification(
|
||||
notification,
|
||||
profileMap[id],
|
||||
@@ -438,21 +583,20 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea
|
||||
false,
|
||||
"",
|
||||
)
|
||||
} else {
|
||||
// register that a notification was not sent
|
||||
a.NotificationsLog().Debug("Notification not sent",
|
||||
mlog.String("ackId", ""),
|
||||
mlog.String("type", model.PushTypeMessage),
|
||||
mlog.String("userId", id),
|
||||
mlog.String("postId", post.Id),
|
||||
mlog.String("status", model.PushNotSent),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, id := range notificationsForCRT.Push {
|
||||
if profileMap[id] == nil {
|
||||
a.NotificationsLog().Warn("Missing profile",
|
||||
mlog.String("type", model.TypePush),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusNotSent),
|
||||
mlog.String("reason", model.ReasonMissingProfile),
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("receiver_id", id),
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -462,7 +606,7 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea
|
||||
status = &model.Status{UserId: id, Status: model.StatusOffline, Manual: false, LastActivityAt: 0, ActiveChannel: ""}
|
||||
}
|
||||
|
||||
if DoesStatusAllowPushNotification(profileMap[id].NotifyProps, status, post.ChannelId) {
|
||||
if statusReason := DoesStatusAllowPushNotification(profileMap[id].NotifyProps, status, post.ChannelId); statusReason == "" {
|
||||
a.sendPushNotification(
|
||||
notification,
|
||||
profileMap[id],
|
||||
@@ -471,18 +615,32 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea
|
||||
model.CommentsNotifyCRT,
|
||||
)
|
||||
} else {
|
||||
// register that a notification was not sent
|
||||
a.NotificationsLog().Debug("Notification not sent",
|
||||
mlog.String("ackId", ""),
|
||||
mlog.String("type", model.PushTypeMessage),
|
||||
mlog.String("userId", id),
|
||||
mlog.String("postId", post.Id),
|
||||
mlog.String("status", model.PushNotSent),
|
||||
a.NotificationsLog().Debug("Notification not sent - status",
|
||||
mlog.String("type", model.TypePush),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusNotSent),
|
||||
mlog.String("reason", model.ReasonUserConfig),
|
||||
mlog.String("status_reason", statusReason),
|
||||
mlog.String("sender_id", post.UserId),
|
||||
mlog.String("receiver_id", id),
|
||||
mlog.String("receiver_status", status.Status),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
a.NotificationsLog().Trace("Finished sending push notifications",
|
||||
mlog.String("type", model.TypePush),
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("post_id", post.Id),
|
||||
)
|
||||
}
|
||||
|
||||
a.NotificationsLog().Trace("Begin sending websocket notifications",
|
||||
mlog.String("type", model.TypeWebsocket),
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("post_id", post.Id),
|
||||
)
|
||||
|
||||
message := model.NewWebSocketEvent(model.WebsocketEventPosted, "", post.ChannelId, "", nil, "")
|
||||
|
||||
message.Add("channel_type", channel.Type)
|
||||
@@ -520,12 +678,28 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea
|
||||
|
||||
published, err := a.publishWebsocketEventForPermalinkPost(c, post, message)
|
||||
if err != nil {
|
||||
a.NotificationsLog().Error("Couldn't send websocket notification for permalink post",
|
||||
mlog.String("type", model.TypeWebsocket),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusServerError),
|
||||
mlog.String("reason", model.ReasonFetchError),
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.Err(err),
|
||||
)
|
||||
return nil, err
|
||||
}
|
||||
if !published {
|
||||
removePermalinkMetadataFromPost(post)
|
||||
postJSON, jsonErr := post.ToJSON()
|
||||
if jsonErr != nil {
|
||||
a.NotificationsLog().Error("JSON parse error",
|
||||
mlog.String("type", model.TypeWebsocket),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusServerError),
|
||||
mlog.String("reason", model.ReasonServerError),
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.Err(err),
|
||||
)
|
||||
return nil, errors.Wrapf(jsonErr, "failed to encode post to JSON")
|
||||
}
|
||||
message.Add("post", postJSON)
|
||||
@@ -539,6 +713,14 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea
|
||||
// A user following a thread but had left the channel won't get a notification
|
||||
// https://mattermost.atlassian.net/browse/MM-36769
|
||||
if profileMap[uid] == nil {
|
||||
a.NotificationsLog().Warn("Missing profile",
|
||||
mlog.String("type", model.TypeWebsocket),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusNotSent),
|
||||
mlog.String("reason", model.ReasonMissingProfile),
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("receiver_id", uid),
|
||||
)
|
||||
continue
|
||||
}
|
||||
if a.IsCRTEnabledForUser(c, uid) {
|
||||
@@ -547,15 +729,41 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea
|
||||
if threadMembership == nil {
|
||||
tm, err := a.Srv().Store().Thread().GetMembershipForUser(uid, post.RootId)
|
||||
if err != nil {
|
||||
a.NotificationsLog().Error("Missing thread membership",
|
||||
mlog.String("type", model.TypeWebsocket),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusServerError),
|
||||
mlog.String("reason", model.ReasonFetchError),
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("receiver_id", uid),
|
||||
mlog.Err(err),
|
||||
)
|
||||
return nil, errors.Wrapf(err, "Missing thread membership for participant in notifications. user_id=%q thread_id=%q", uid, post.RootId)
|
||||
}
|
||||
if tm == nil {
|
||||
a.NotificationsLog().Warn("Missing thread membership",
|
||||
mlog.String("type", model.TypeWebsocket),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusNotSent),
|
||||
mlog.String("reason", model.ReasonServerError),
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("receiver_id", uid),
|
||||
)
|
||||
continue
|
||||
}
|
||||
threadMembership = tm
|
||||
}
|
||||
userThread, err := a.Srv().Store().Thread().GetThreadForUser(threadMembership, true, a.IsPostPriorityEnabled())
|
||||
if err != nil {
|
||||
a.NotificationsLog().Error("Missing thread",
|
||||
mlog.String("type", model.TypeWebsocket),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusServerError),
|
||||
mlog.String("reason", model.ReasonFetchError),
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("receiver_id", uid),
|
||||
mlog.Err(err),
|
||||
)
|
||||
return nil, errors.Wrapf(err, "cannot get thread %q for user %q", post.RootId, uid)
|
||||
}
|
||||
if userThread != nil {
|
||||
@@ -580,6 +788,15 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea
|
||||
// should set unread mentions, and unread replies to 0
|
||||
_, err = a.Srv().Store().Thread().MaintainMembership(uid, post.RootId, opts)
|
||||
if err != nil {
|
||||
a.NotificationsLog().Error("Failed to update thread membership",
|
||||
mlog.String("type", model.TypeWebsocket),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusServerError),
|
||||
mlog.String("reason", model.ReasonServerError),
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("receiver_id", uid),
|
||||
mlog.Err(err),
|
||||
)
|
||||
return nil, errors.Wrapf(err, "cannot maintain thread membership %q for user %q", post.RootId, uid)
|
||||
}
|
||||
userThread.UnreadMentions = 0
|
||||
@@ -590,6 +807,15 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea
|
||||
|
||||
sanitizedPost, err := a.SanitizePostMetadataForUser(c, userThread.Post, uid)
|
||||
if err != nil {
|
||||
a.NotificationsLog().Error("Failed to sanitize metadata",
|
||||
mlog.String("type", model.TypeWebsocket),
|
||||
mlog.String("post_id", post.Id),
|
||||
mlog.String("status", model.StatusServerError),
|
||||
mlog.String("reason", model.ReasonServerError),
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("receiver_id", uid),
|
||||
mlog.Err(err),
|
||||
)
|
||||
return nil, err
|
||||
}
|
||||
userThread.Post = sanitizedPost
|
||||
@@ -607,6 +833,13 @@ func (a *App) SendNotifications(c request.CTX, post *model.Post, team *model.Tea
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a.NotificationsLog().Trace("Finish sending websocket notifications",
|
||||
mlog.String("type", model.TypeWebsocket),
|
||||
mlog.String("sender_id", sender.Id),
|
||||
mlog.String("post_id", post.Id),
|
||||
)
|
||||
|
||||
return mentionedUsersList, nil
|
||||
}
|
||||
|
||||
|
||||
Ссылка в новой задаче
Block a user