Oh Dear is the all-in-one monitoring tool for your entire website. We monitor uptime, SSL certificates, broken links, scheduled tasks and more. You'll get a notifications for us when something's wrong. All that paired with a developer friendly API and kick-ass documentation. O, and you'll also be able to create a public status page under a minute. Start monitoring using our free trial now.

A package to display solutions on the Laravel error page

Original – by Freek Van der Herten – 7 minute read

When Laravel switched to a simpler exception page, the ability to display solutions for an exception was lost.

Our latest package, called spatie/laravel-error-solutions brings back that powerful feature. When installed, it will display solutions for most common exceptions.

Here’s how that looks it:

And yes, some solutions, like the one in the screenshot above, can be executed on the exception page too.

In this blog post, I’d like to tell you all about it!

Displaying and running solutions

Getting started with the package is quite easy. Just install it using Composer, and you’re done.

composer require spatie/laravel-error-solutions

When you now get an exception the package knows a solution for, it will display it on the exception page.

Here’s how that looks like when you slightly misspell a method name

For some solutions, the package will display a button that will automatically run the solution. Here's how that looks when you forget to set the APP_KEY in your .env file.

When you click that button, an app key will be generated and saved in your .env file. Pretty sweet!

Another handy runnable solutions is when you an exception occurs when saving a model, and one of its attributes does not have a column in the database. Probably you should forgot to run migration. Well the package has a runnable solution for that common mistake as well.

Runnable solutions will only be available in local development environments. The package contains a dedicated class to determine when it’s save to run a solution.

AI-powered solutions

The package comes with a nice collection of solution for common exceptions. Of course, we can’t foresee each and every possible exception.

However, the package can send exceptions to Open AI to automatically suggest a solution. In many cases, the suggested solutions are quite useful, but keep in mind that the solution may not be 100% correct for your context.

To generate AI powered solutions, you must first install this optional dependency.

composer require openai-php/client

To send your errors to OpenAI, you must set ERROR_SOLUTIONS_OPEN_AI_KEY in your .env file. The value should be your OpenAI key.

These bits of info will be sent to Open AI:

  • the error message
  • the error class
  • the stack frame
  • other small bits of info of context surrounding your error

It will not send the request payload or any environment variables to avoid sending sensitive data to OpenAI.

Creating your own solutions

In addition to the built-in solution and AI solutions, you can define your own solutions for your particular exceptions.

First, you need to create a Solution class: a simple PHP class that implements the Spatie\ErrorSolutions\Contracts\Solution interface.

Here's a simple example.

class MySolution implements Solution
{
    public function getSolutionTitle(): string
    {
        return 'My custom solution';
    }

    public function getSolutionDescription(): string
    {
        return 'My custom solution description';
    }

    public function getDocumentationLinks(): array
    {
        return [
            'Spatie docs' => 'https://spatie.be/docs',
        ];
    }
}

Optionally, you can add "provided by" information to a solution by implementing these methods.

// in your solution class

public function solutionProvidedByName(): string
{
    return 'Flare';
}

public function solutionProvidedByLink(): string
{
    return 'https://flareapp.io';
}

You can add a solution to an exception directly. Let your exception implement the ProvidesSolution interface and let the getSolution method return your solution.

use Exception;
use Spatie\ErrorSolutions\Contracts\Solution;
use Spatie\ErrorSolutions\Contracts\ProvidesSolution;

class ExceptionWithSolution extends Exception implements ProvidesSolution
{
    public function __construct(string $message = '')
    {
        parent::__construct($message ?? 'My custom exception');
    }

    public function getSolution(): Solution
    {
        return YourSolution::class,
    }
}

If you want to add solutions to exceptions that you can't modify, you can use a solution provider. A solution provider is a class that implements the ProvidesSolution interface. It will determine if it can provide a solution for a given exception.

Here's an example:

use Spatie\ErrorSolutions\Contracts\HasSolutionsForThrowable;
use Spatie\ErrorSolutions\Contracts\Solution;
use Throwable;

class YourSolutionProvider implements HasSolutionsForThrowable
{
    public function canSolve(Throwable $throwable): bool
    {
        // return true if you can provide a solution for this exception
    }

    /**
     * @param \Throwable $throwable
     *
     * @return array<int, Solution>
     */
    public function getSolutions(Throwable $throwable): array
    {
        // return an array of solutions
    }
}

After you've created your solution provider, you can register it in the solution_providers key of the error-solutions.php config file:

// config/error-solutions.php

return [
    'solution_providers' => [
        // other solution providers
        YourSolutionProvider::class,
    ],
];

Alternatively, you can register your solution provider at runtime. Typically, this would be done in a service provider:

// app/Providers/YourServiceProvider.php

use Spatie\ErrorSolutions\ErrorSolutionsServiceProvider;
use Spatie\ErrorSolutions\Contracts\SolutionProviderRepository;

public function register()
{
    $repository = app(SolutionProviderRepository::class);
    
    $repository->registerSolutionProviders([
        YourSolutionProvider::class,
    ]);
}

Seeing solutions in production environments

Laravel’s error page displays sensitive information, and it should never be shown in production environments. If debug mode is enabled in production environments, you’re doing something wrong.

However, it is still possible to see solutions for production environments. At Spatie, we built Flare, an exception tracker built for Laravel apps. It displays all important information around an exception in a beautiful, easy-to-use UI.

When you use Flare as your exception tracker, solutions will also be generated and displayed. Here’s how that looks like.

You can try Flare using our free 10-day trial.

How the package works under the hood

Let’s take a look at how we manage to hook into Laravel’s error page.

The Laravel error page consists of a couple of Blade views that are registered using the laravel-exceptions-renderer view namespace.

In our service provider, we register our own view directory under the same namespace.

View::prependNamespace('laravel-exceptions-renderer', [
    __DIR__.'/../resources/views',
]);

This means that Laravel will look in our view directory first when in tries to render the error page.

We render the solutions in the header part of the error page. In our views directory, we have a file header.blade.php that contains the same content as the file with the same name in the framework. So Laravel will use our header.blade.php file instead of the one that ships with the framework.

In our header.blade.php we’ve added one line near the end.

<x-laravel-exceptions-renderer::solution />

So in addition to the normal header, we also render the solution.blade.php file that ships with the package.

That solution.blade.php file, which is a bit too lengthy to inline in this blog post, contains everything regarding solutions: we call an action to determine the solutions, the styling of the solution, and the necessary HTML.

In closing

Our Laravel Error Solutions package can help you fix your exceptions faster by displaying a solution right next to the exception locally.

If you want this ability for your production environment, check out Flare.

Of course, this package isn’t the first we built. At Spatie, we have a big heart for open source. You’ll find a list of all of our packages here.

Want to support us? Consider buying one of our paid products, or subscribe to Mailcoach or Flare.

Stay up to date with all things Laravel, PHP, and JavaScript.

You can follow me on these platforms:

On all these platforms, regularly share programming tips, and what I myself have learned in ongoing projects.

Every month I send out a newsletter containing lots of interesting stuff for the modern PHP developer.

Expect quick tips & tricks, interesting tutorials, opinions and packages. Because I work with Laravel every day there is an emphasis on that framework.

Rest assured that I will only use your email address to send you the newsletter and will not use it for any other purposes.

Comments

govib avatar

How I can return? The player is stumped, they can opt to skip or guess, unlocking more of the song heardle unlimited.

aspecthjl avatar

Spunki Incredibox is an interactive music creation game where players use unique Sprunki characters to create their own music. Each character has distinct sounds, allowing you to experiment and craft your unique musical style.

Ethan avatar

I’m not sure how much I'd rely on the AI-suggested solutions. Sometimes, they can be a bit off, depending on the error. Still, for common mistakes, like forgetting migrations or APP_KEY, it could be a real time-saver. super mario 64

Comments powered by Laravel Comments
Want to join the conversation? Log in or create an account to post a comment.