Skip to content

Commit

Permalink
Merge pull request #7433 from TheThingsNetwork/fix/unknown-notifications
Browse files Browse the repository at this point in the history
Fix console crash when receiving unknown notification type
  • Loading branch information
ryaplots authored Dec 16, 2024
2 parents 7ebe8d7 + 7a2158e commit 0186265
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 6 deletions.
13 changes: 13 additions & 0 deletions pkg/webui/console/components/notifications/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import { ingestError } from '@ttn-lw/lib/errors/utils'

import notificationMap from './constants'

export const getNotification = notificationType => notificationMap[notificationType]
Expand All @@ -25,5 +27,16 @@ const idToEntityMap = {
client_ids: 'client',
}

export const validateNotification = (notificationType, ingestedBy) => {
if (!(notificationType in notificationMap)) {
ingestError(new Error(`Notification type "${notificationType}" does not exist`), {
ingestedBy,
})
return false
}

return true
}

export const getEntity = entity_ids =>
(entity_ids && idToEntityMap[Object.keys(entity_ids)[0]]) || 'entity'
54 changes: 48 additions & 6 deletions pkg/webui/console/store/middleware/logics/notifications.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import tts from '@console/api/tts'

import toast from '@ttn-lw/components/toast'

import { validateNotification } from '@console/components/notifications/utils'

import NOTIFICATION_STATUS from '@console/containers/notifications/notification-status'

import createRequestLogic from '@ttn-lw/lib/store/logics/create-request-logic'
Expand Down Expand Up @@ -74,10 +76,17 @@ const getInboxNotificationsLogic = createRequestLogic({
const filter = [NOTIFICATION_STATUS.UNSEEN, NOTIFICATION_STATUS.SEEN]
const userId = selectUserId(getState())
const result = await tts.Notifications.getAllNotifications(userId, filter, page, limit)
// Remove unknown notification types from the result and send error to Sentry.
// When a new notification type is introduced in the backend, this will prevent
// the Console from crashing.
const validatedResult = result.notifications.filter(notification =>
validateNotification(notification.notification_type, 'getInboxNotificationsLogic'),
)

return {
notifications: result.notifications,
totalCount: result.totalCount,
notifications: validatedResult,
// Subtract the number of unknown notification types from the total count.
totalCount: result.totalCount - (result.notifications.length - validatedResult.length),
page,
limit,
}
Expand Down Expand Up @@ -106,17 +115,26 @@ const refreshNotificationsLogic = createRequestLogic({
1,
1,
)
// Remove unknown notification types from the result and send error to Sentry.
// When a new notification type is introduced in the backend, this will prevent
// the Console from crashing.
const validatedUnseen = unseen.notifications.filter(notification =>
validateNotification(notification.notification_type, 'refreshNotificationsLogic'),
)

// Subtract the number of unknown notification types from the total count.
const validatedUnseenCount =
unseen.totalCount - (unseen.notifications.length - validatedUnseen.length)
// If there are new unseen notifications, show a toast and fetch the notifications.
if (unseen && unseen.totalCount > prevTotalUnseenCount) {
if (unseen && validatedUnseenCount > prevTotalUnseenCount) {
toast({
title: m.newNotifications,
type: toast.types.INFO,
})
await dispatch(attachPromise(notifications.getInboxNotifications()))
}

return { unseenTotalCount: unseen?.totalCount }
return { unseenTotalCount: validatedUnseenCount }
},
})

Expand All @@ -129,8 +147,20 @@ const getArchivedNotificationsLogic = createRequestLogic({
const filter = [NOTIFICATION_STATUS.ARCHIVED]
const userId = selectUserId(getState())
const result = await tts.Notifications.getAllNotifications(userId, filter, page, limit)
// Remove unknown notification types from the result and send error to Sentry.
// When a new notification type is introduced in the backend, this will prevent
// the Console from crashing.
const validatedResult = result.notifications.filter(notification =>
validateNotification(notification.notification_type, 'getArchivedNotificationsLogic'),
)

return { notifications: result.notifications, totalCount: result.totalCount, page, limit }
return {
notifications: validatedResult,
// Subtract the number of unknown notification types from the total count.
totalCount: result.totalCount - (result.notifications.length - validatedResult.length),
page,
limit,
}
},
})

Expand All @@ -143,8 +173,20 @@ const getUnseenNotificationsLogic = createRequestLogic({
const filter = [NOTIFICATION_STATUS.UNSEEN]
const userId = selectUserId(getState())
const result = await tts.Notifications.getAllNotifications(userId, filter, page, limit)
// Remove unknown notification types from the result and send error to Sentry.
// When a new notification type is introduced in the backend, this will prevent
// the Console from crashing.
const validatedResult = result.notifications.filter(notification =>
validateNotification(notification.notification_type, 'getUnseenNotificationsLogic'),
)

return { notifications: result.notifications, totalCount: result.totalCount, page, limit }
return {
notifications: validatedResult,
// Subtract the number of unknown notification types from the total count.
totalCount: result.totalCount - (result.notifications.length - validatedResult.length),
page,
limit,
}
},
})

Expand Down

0 comments on commit 0186265

Please sign in to comment.