Skip to content
This repository has been archived by the owner on Oct 23, 2023. It is now read-only.

[DOCS] Django Integration for User Feedback #945

Open
audiolion opened this issue Jan 25, 2017 · 6 comments
Open

[DOCS] Django Integration for User Feedback #945

audiolion opened this issue Jan 25, 2017 · 6 comments

Comments

@audiolion
Copy link

The docs for user feedback integration with Django state that it is as simple as dropping that into the 500.html template. However, this is incorrect.

Django's default server_error() view passes an empty context variable so the template renders and the {% if request.sentry.id %} line always results in False because there is no request object passed back (empty context dict).

The resolution is stated in the docs where it references a custom handler500() view that passes the context. I feel like that needs to be included down in the User Feedback section somewhere, and can submit a PR if you'd like.

The new documentation for User Feedback would look something like:

User Feedback

By default Django will render 500.html, so simply drop the following snippet into your template:

<!-- Sentry JS SDK 2.1.+ required -->
<script src="https://cdn.ravenjs.com/2.3.0/raven.min.js"></script>

{% if request.sentry.id %}
  <script>
  Raven.showReportDialog({
    eventId: '{{ request.sentry.id }}',

    // use the public DSN (dont include your secret!)
    dsn: '___PUBLIC_DSN___'
  });
  </script>
{% endif %}

Then override the default 500 handler to include the context information. In your URL Conf (base urls.py) add:

handler500 = 'myapp.views.sentry_server_error'

Then define that view as:

from django import http
from django.template import Context, RequestContext, TemplateDoesNotExist, loader
from django.views.decorators.csrf import requires_csrf_token


@requires_csrf_token
def sentry_server_error(request, template_name='500.html'):
    try:
        template = loader.get_template(template_name)
    except TemplateDoesNotExist:
        return http.HttpResponseServerError('<h1>Server Error (500)</h1>', content_type='text/html')
    return http.HttpResponseServerError(template.render(RequestContext(request)))

Note

Because Django's default server_error() passes an empty context variable we need to create a custom 500 error handler to pass the request context.

@dcramer
Copy link
Member

dcramer commented Jan 29, 2017

I suppose we could do provide a built-in replacement to server_error which handles passing in the required context from Sentry. There's good reasons you don't want context in general to be available, but we can guarantee safety around things we provide.

@jaaved
Copy link

jaaved commented May 8, 2018

In django >= 2.0

@requires_csrf_token
def sentry_server_error(request, template_name=ERROR_500_TEMPLATE_NAME):
    """
    500 error handler.

    Templates: :template:`500.html`
    Context: None
    """
    try:
        template = loader.get_template(template_name)
    except TemplateDoesNotExist:
        if template_name != ERROR_500_TEMPLATE_NAME:
            # Reraise if it's a missing custom template.
            raise
        return HttpResponseServerError('<h1>Server Error (500)</h1>', content_type='text/html')
    #return HttpResponseServerError(template.render(RequestContext(request))) # instead of this; to avoid TypeError
    return HttpResponseServerError(template.render(context=None, request=request))

@epicserve
Copy link

@dcramer,

FYI, I just ran into this as well. The docs don't mention using a custom 500 view right now either.

@epicserve
Copy link

I guess It does say something in the Message Reference section, but I missed it because there wasn't anything in the User Feedback Section.

https://docs.sentry.io/clients/python/integrations/django/#message-references

@epicserve
Copy link

Also as an FYI you might want to suggest a server error view like the following so you can dynamically insert the dsn.

from urllib.parse import urlparse

def server_error(request):

    # Use the 500 template for each program if it exists
    url_segment = request.path_info.strip("/").split("/")
    program_500_template = "%s/500.html" % url_segment[0]
    t = loader.select_template([program_500_template, '500.html'])

    sentry_dsn = None
    if hasattr(settings, 'RAVEN_CONFIG') is True and 'dsn' in settings.RAVEN_CONFIG and settings.RAVEN_CONFIG['dsn']:
        # strip out the password
        url_obj = urlparse(settings.RAVEN_CONFIG['dsn'])
        sentry_dsn = '{scheme}://{username}@{hostname}{path}'.format(scheme=url_obj.scheme, username=url_obj.username, hostname=url_obj.hostname, path=url_obj.path)

    context_dict = {'request': request, 'sentry_dsn': sentry_dsn}
    return HttpResponseServerError(t.render(context_dict))

@AzyCrw4282
Copy link

AzyCrw4282 commented Nov 12, 2021

I also came across this error today. I was following the docs here and inconveniently it doesn't mention the step of overriding the 500 handler. If you follow that as shown in the top answer and then the rest of the code in the docs will help solve the problem.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants