fix: Add catch for additional webpush errors (#9662)
Webpush gem throws errors such as `WebPush::ExpiredSubscription`, `WebPush::InvalidSubscription`, `WebPush::Unauthorized`. We handled only ExpiredSubscription. If the SDK threw any other errors, it would pause sending the notification to all other devices for that user. This change would update the logic to remove the expired subscription and handle the rest of the errors gracefully. Fixes https://linear.app/chatwoot/issue/CW-3399/webpushinvalidsubscription-host-fcmgoogleapiscom-nethttpnotfound-404
This commit is contained in:
@@ -42,14 +42,12 @@ class Notification::PushNotificationService
|
||||
app_account_conversation_url(account_id: conversation.account_id, id: conversation.display_id)
|
||||
end
|
||||
|
||||
def send_browser_push?(subscription)
|
||||
def can_send_browser_push?(subscription)
|
||||
VapidService.public_key && subscription.browser_push?
|
||||
end
|
||||
|
||||
def send_browser_push(subscription)
|
||||
return unless send_browser_push?(subscription)
|
||||
|
||||
WebPush.payload_send(
|
||||
def browser_push_payload(subscription)
|
||||
{
|
||||
message: JSON.generate(push_message),
|
||||
endpoint: subscription.subscription_attributes['endpoint'],
|
||||
p256dh: subscription.subscription_attributes['p256dh'],
|
||||
@@ -62,11 +60,22 @@ class Notification::PushNotificationService
|
||||
ssl_timeout: 5,
|
||||
open_timeout: 5,
|
||||
read_timeout: 5
|
||||
)
|
||||
rescue WebPush::ExpiredSubscription
|
||||
}
|
||||
end
|
||||
|
||||
def send_browser_push(subscription)
|
||||
return unless can_send_browser_push?(subscription)
|
||||
|
||||
WebPush.payload_send(browser_push_payload(subscription))
|
||||
Rails.logger.info("Browser push sent to #{user.email} with title #{push_message[:title]}")
|
||||
rescue WebPush::ExpiredSubscription, WebPush::InvalidSubscription, WebPush::Unauthorized => e
|
||||
Rails.logger.info "WebPush subscription expired: #{e.message}"
|
||||
subscription.destroy!
|
||||
rescue Errno::ECONNRESET, Net::OpenTimeout, Net::ReadTimeout => e
|
||||
Rails.logger.error "WebPush operation error: #{e.message}"
|
||||
rescue StandardError => e
|
||||
ChatwootExceptionTracker.new(e, account: notification.account).capture_exception
|
||||
true
|
||||
end
|
||||
|
||||
def send_fcm_push(subscription)
|
||||
@@ -98,7 +107,11 @@ class Notification::PushNotificationService
|
||||
end
|
||||
|
||||
def remove_subscription_if_error(subscription, response)
|
||||
subscription.destroy! if JSON.parse(response[:body])['results']&.first&.keys&.include?('error')
|
||||
if JSON.parse(response[:body])['results']&.first&.keys&.include?('error')
|
||||
subscription.destroy!
|
||||
else
|
||||
Rails.logger.info("FCM push sent to #{user.email} with title #{push_message[:title]}")
|
||||
end
|
||||
end
|
||||
|
||||
def fcm_options(subscription)
|
||||
|
||||
Reference in New Issue
Block a user