getsentry / sentry-python

The official Python SDK for Sentry.io
https://sentry.io/for/python/
MIT License
1.93k stars 510 forks source link

`sentry_sdk.init` throws an exception on Django 5.0a1 #2383

Closed anze3db closed 1 year ago

anze3db commented 1 year ago

How do you use Sentry?

Sentry Saas (sentry.io)

Version

1.31.0

Steps to Reproduce

  1. Have a Django project with Sentry integration (https://docs.sentry.io/platforms/python/guides/django/)
  2. Install the Django 5.0 alpha1: `pip install "django==5.0a1"
  3. Start the server python manage.py runserver

Expected Result

No exception raised.

Actual Result

The following exception was thrown:

python manage.py runserver      
Watching for file changes with StatReloader
Performing system checks...

Traceback (most recent call last):
  File "/Users/anze/coding/fedidevs/manage.py", line 22, in <module>
    main()
  File "/Users/anze/coding/fedidevs/manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "/Users/anze/coding/fedidevs/.venv/lib/python3.11/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
    utility.execute()
  File "/Users/anze/coding/fedidevs/.venv/lib/python3.11/site-packages/django/core/management/__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/anze/coding/fedidevs/.venv/lib/python3.11/site-packages/django/core/management/base.py", line 412, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/Users/anze/coding/fedidevs/.venv/lib/python3.11/site-packages/django/core/management/commands/runserver.py", line 74, in execute
    super().execute(*args, **options)
  File "/Users/anze/coding/fedidevs/.venv/lib/python3.11/site-packages/django/core/management/base.py", line 458, in execute
    output = self.handle(*args, **options)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/anze/coding/fedidevs/.venv/lib/python3.11/site-packages/django/core/management/commands/runserver.py", line 111, in handle
    self.run(**options)
  File "/Users/anze/coding/fedidevs/.venv/lib/python3.11/site-packages/django/core/management/commands/runserver.py", line 118, in run
    autoreload.run_with_reloader(self.inner_run, **options)
  File "/Users/anze/coding/fedidevs/.venv/lib/python3.11/site-packages/django/utils/autoreload.py", line 671, in run_with_reloader
    start_django(reloader, main_func, *args, **kwargs)
  File "/Users/anze/coding/fedidevs/.venv/lib/python3.11/site-packages/django/utils/autoreload.py", line 660, in start_django
    reloader.run(django_main_thread)
  File "/Users/anze/coding/fedidevs/.venv/lib/python3.11/site-packages/django/utils/autoreload.py", line 343, in run
    autoreload_started.send(sender=self)
  File "/Users/anze/coding/fedidevs/.venv/lib/python3.11/site-packages/django/dispatch/dispatcher.py", line 187, in send
    sync_receivers, async_receivers = self._live_receivers(sender)
                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/anze/coding/fedidevs/.venv/lib/python3.11/site-packages/sentry_sdk/integrations/django/signals_handlers.py", line 73, in _sentry_live_receivers
    receivers[idx] = sentry_receiver_wrapper(receiver)
    ~~~~~~~~~^^^^^
TypeError: 'tuple' object does not support item assignment

Django added support for async handlers in 5.0 which changed the return value of Signal._live_receivers. The relevant commit that broke Sentry's integration: https://github.com/django/django/commit/e83a88566a71a2353cebc35992c110be0f8628af

sentrivana commented 1 year ago

Hey @anze3db, thanks for the heads up and for pointing us to the commit! We'll need to fix this and whatever other potential compat issues there are with 5.0. (PRs are of course more than welcome!)

vincentdavis commented 1 year ago

The bug seems to be caused by Django singles now having an async option. Take a look here. Django commit

Problems lines

Possibly, this could be fixed by modifying this line (72) from for idx, receiver in enumerate(receivers): to for idx, receiver in enumerate(receivers[0]): This would get the sync receivers, which I am guessing is what was used before.

antonpirker commented 1 year ago

Thanks for the investigation @vincentdavis We will take this into account when we make Sentry SDK ready for Django 5!