User Feedback

Sentry provides the ability to collect additional feedback from the user upon hitting an error. This is primarily useful in situations where you might generally render a plain error page (the classic 500.html). To collect the feedback, an embeddable JavaScript widget is available, which can then be shown on demand to your users.

The following pieces of information are requested and collected:

  • The user’s name
  • The user’s email address
  • A description of what happened

When feedback is collected, Sentry will pair it up with the original event giving you additional insights into issues.

Collecting Feedback

The integration process consists of running our JavaScript SDK (2.1 or newer), authenticating with your public DSN, and passing in the client-side generated Event ID:

With ASP.NET Core MVC, the Error.cshtml razor page:

<script src="https://browser.sentry-cdn.com/5.5.0/bundle.min.js" crossorigin="anonymous"></script>

@using Sentry

@if (SentrySdk.LastEventId != Guid.Empty)
{
    <script>
        Sentry.init({ dsn: '___PUBLIC_DSN___' });
        Sentry.showReportDialog({ eventId: '@SentrySdk.LastEventId' });
    </script>
}

If you’re using a framework like React or Angular, the best place to collect user feedback is in your error-handling component. (Please see platform-specific docs for examples.) If you’re not using a framework, you can collect feedback right before the event is sent, using beforeSend:

<script src="https://browser.sentry-cdn.com/5.5.0/bundle.min.js" crossorigin="anonymous"></script>

<script>
  Sentry.init({
    dsn: '___PUBLIC_DSN___',
    beforeSend(event, hint) {
      // Check if it is an exception, and if so, show the report dialog
      if (event.exception) {
        Sentry.showReportDialog({ eventId: event.event_id });
      }
      return event;
    }
  });
</script>

Custom 500 handler:

from sentry_sdk import last_event_id
from django.shortcuts import render

def handler500(request, *args, **argv):
    return render(request, "500.html", {
        'sentry_event_id': last_event_id(),
    }, status=500)

And the template that brings up the dialog

<script src="https://browser.sentry-cdn.com/5.5.0/bundle.min.js" crossorigin="anonymous"></script>

{% if sentry_event_id %}
<script>
  Sentry.init({ dsn: '___PUBLIC_DSN___' });
  Sentry.showReportDialog({ eventId: '{{ sentry_event_id }}' })
</script>
{% endif %}

const { init, showReportDialog } = require('@sentry/electron');

init({
  dsn: '___PUBLIC_DSN___',
  beforeSend(event) {
    // Check if it is an exception, if so, show the report dialog
    // Note that this only will work in the renderer process, it's a noop on the main process
    if (event.exception) {
      showReportDialog();
    }
    return event;
  }
});

Custom 500 handler:

from flask import render_template
from sentry_sdk import last_event_id

@app.errorhandler(500)
def server_error_handler(error):
    return render_template("500.html", sentry_event_id=last_event_id()), 500

And the template that brings up the dialog:

<script src="https://browser.sentry-cdn.com/5.5.0/bundle.min.js" crossorigin="anonymous"></script>

{% if sentry_event_id %}
<script>
  Sentry.init({ dsn: '___PUBLIC_DSN___' });
  Sentry.showReportDialog({ eventId: '{{ sentry_event_id }}' })
</script>
{% endif %}

For Laravel 5 up to 5.4 you need to open up App/Exceptions/Handler.php and extend the render method to make sure the 500 error is rendered as a view correctly, in 5.5+ this step is not required anymore and you can skip ahead to the next one:

<?php

use Symfony\Component\HttpKernel\Exception\HttpException;

class Handler extends ExceptionHandler
{
    public function report(Exception $exception)
    {
        if (app()->bound('sentry') && $this->shouldReport($exception)) {
            app('sentry')->captureException($exception);
        }

        parent::report($exception);
    }

    public function render($request, Exception $exception)
    {
        // Convert all non-http exceptions to a proper 500 http exception
        // if we don't do this exceptions are shown as a default template
        // instead of our own view in resources/views/errors/500.blade.php
        if ($this->shouldReport($exception) && !$this->isHttpException($exception) && !config('app.debug')) {
            $exception = new HttpException(500, 'Whoops!');
        }

        return parent::render($request, $exception);
    }
}

Next, create resources/views/errors/500.blade.php, and embed the feedback code:

<div class="content">
    <div class="title">Something went wrong.</div>

    @if(app()->bound('sentry') && app('sentry')->getLastEventId())
        <div class="subtitle">Error ID: </div>
        <script src="https://browser.sentry-cdn.com/5.5.0/bundle.min.js" crossorigin="anonymous"></script>
        <script>
            Sentry.init({ dsn: '___PUBLIC_DSN___' });
            Sentry.showReportDialog({ eventId: '' });
        </script>
    @endif
</div>

This function php returns the last eventId:

Sentry\State\Hub::getCurrent()->getLastEventId();

Depending on how you render your templates, the example would be in a simple php file:

<script src="https://browser.sentry-cdn.com/5.5.0/bundle.min.js" crossorigin="anonymous"></script>

<?php if (Sentry\State\Hub::getCurrent()->getLastEventId()) { ?>
<script>
  Sentry.init({ dsn: '___PUBLIC_DSN___' });
  Sentry.showReportDialog({ eventId: '<?php echo Sentry\State\Hub::getCurrent()->getLastEventId(); ?>' })
</script>
<?php } ?>

If you don’t want to use Sentry’s native widget, you can also send feedback using our User Feedback API.

Customizing the Widget

Several parameters are available to customize the widget, specifically for localization. All options can be passed through the showReportDialog call.

An override for Sentry’s automatic language detection (e.g. lang=de)

Param Default
eventId Manually set the id of the event.
dsn Manually set dsn to report to.
user Manually set user data [an object with keys listed above].
user.email User’s email address.
user.name User’s name.
lang [automatic]override for Sentry’s language code
title It looks like we’re having issues.
subtitle Our team has been notified.
subtitle2 If you’d like to help, tell us what happened below. – not visible on small screen resolutions
labelName Name
labelEmail Email
labelComments What happened?
labelClose Close
labelSubmit Submit
errorGeneric An unknown error occurred while submitting your report. Please try again.
errorFormEntry Some fields were invalid. Please correct the errors and try again.
successMessage Your feedback has been sent. Thank you!
onLoad n/a