Skip to content

Improve error web push treatments #771

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions push_notifications/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,12 +242,11 @@ def get_queryset(self):

class WebPushDeviceQuerySet(models.query.QuerySet):
def send_message(self, message, **kwargs):
from .webpush import webpush_send_bulk_message
devices = self.filter(active=True).order_by("application_id").distinct()
res = []
for device in devices:
res.append(device.send_message(message))

return res
ret = []
ret.append(webpush_send_bulk_message(devices, message, **kwargs))
return ret


class WebPushDevice(Device):
Expand Down
61 changes: 50 additions & 11 deletions push_notifications/webpush.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from .conf import get_manager
from .exceptions import WebPushError

from .models import WebPushDevice


def get_subscription_info(application_id, uri, browser, auth, p256dh):
if uri.startswith("https://"):
Expand All @@ -26,12 +28,43 @@ def get_subscription_info(application_id, uri, browser, auth, p256dh):
}


def webpush_send_message(device, message, **kwargs):
def webpush_send_bulk_message(devices, message, **kwargs):
results = {
"success": 0,
"failure": 0,
"results": []}
exception_message = ''
for device in devices:
try:
webpush_send_message(device, message, results=results, **kwargs)
except WebPushError as e:
if exception_message != '':
exception_message += '\n\n'
exception_message += f'{e} device pk: {device.pk}'

ids_to_disable = []
for result in results["results"]:
if "error" in result:
ids_to_disable.append(result["original_registration_id"])
WebPushDevice.objects.filter(registration_id__in=ids_to_disable).update(active=False)

if exception_message:
raise WebPushError(exception_message)

return results


def webpush_send_message(device, message, results=None, **kwargs):
bulk = results is not None
if not bulk:
results = {
"success": 0,
"failure": 0,
"results": []}
subscription_info = get_subscription_info(
device.application_id, device.registration_id,
device.browser, device.auth, device.p256dh)
try:
results = {"results": [{"original_registration_id": device.registration_id}]}
response = webpush(
subscription_info=subscription_info,
data=message,
Expand All @@ -40,16 +73,22 @@ def webpush_send_message(device, message, **kwargs):
**kwargs
)
if response.ok:
results["success"] = 1
results["success"] += 1
results["results"].append({'original_registration_id': device.registration_id})
else:
results["failure"] = 1
results["results"][0]["error"] = response.content
results["failure"] += 1
results["results"].append({'error': response.content,
'original_registration_id': device.registration_id})
return results
except WebPushException as e:
if e.response is not None and e.response.status_code in [404, 410]:
results["failure"] = 1
results["results"][0]["error"] = e.message
device.active = False
device.save()
exception_message = str(e)
if e.response is not None and e.response.status_code in [400, 404, 410]:
results["failure"] += 1
results["results"].append(
{'error': exception_message,
'original_registration_id': device.registration_id})
if not bulk:
device.active = False
device.save(update_fields=('active',))
return results
raise WebPushError(e.message)
raise WebPushError(exception_message)
Loading