getsentry/spotlight

Improve SDK support for server-based 500s

Opened this issue · 0 comments

We need to adjust the way the SDK and Spotlight inteteract to support a better workflow.

Ideal outcome:

  • Server generates an error (e.g. 500 standard uncaught exception)
  • Sentry SDK captures that payload
  • On the framework/user specific error handler (e.g. Django's 500 error handler) we are able to grab the eventID and the full event payload (fully materialized) of the error.

I dont know exactly what this looks like in practice, but in SDKs we already return eventID from things like captureException(). We almost need that kind of behavior, but with the abilty to also grab the event payload.

Implementation wise we should look at Django, Laravel, and Rails. All have error frameworks to make this drop-in. In Laravel, for example, we need to hook it here:

<?php

namespace Spotlight\Laravel;

use Spotlight\Laravel\Renderers;
use Illuminate\Support\ServiceProvider;

class SpotlightServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     */
    public function register(): void
    {
        $this->app->bind(
            'Illuminate\Contracts\Foundation\ExceptionRenderer',
            fn (Application $app) => $app->make(SpotlightExceptionRenderer::class)
        );
    }

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        //
    }
}

The error handler gets passed the exception, which at this point - similar to how User Feedback integration works - we'd need to get the payload. It's possible "the last error generated" is fine (I'm not sure), but "the last event" is probably incorrect these days. Really we want "the last unhandled error" OR we want a clean way to just pull the guaranteed payload of an exception.

On this error page, or on a generic injection thats available everywhere, it then becomes as easy as Spotlight.init() and Spotlight.trigger("sentry:showError", {eventId: event.event_id, event}).

For more clarity on the DX and how it must work, image you have 500.blade.php:

<h1>Internal Server Error</h1>
<StackTrace />

<script>
Spotlight.init();
Spotlight.trigger("sentry:showError", {
  event: {{ app('sentry')->getTheErrorThatCrashedTheServerAsJSON() }}
 });
 </script>