Solutions
Flare can find solutions for the errors thrown in your application.
This functionality is enabled by default, but you can disable it by ignoring the Solutions
collect in config.php
:
use Spatie\FlareClient\Enums\CollectType;
'collects' => FlareConfig::defaultCollects(
ignore: [CollectType::Solutions],
),
By default, the following solutions are collected:
BadMethodCallSolutionProvider
MergeConflictSolutionProvider
UndefinedPropertySolutionProvider
IncorrectValetDbCredentialsSolutionProvider
MissingAppKeySolutionProvider
DefaultDbNameSolutionProvider
TableNotFoundSolutionProvider
MissingImportSolutionProvider
InvalidRouteActionSolutionProvider
ViewNotFoundSolutionProvider
RunningLaravelDuskInProductionProvider
MissingColumnSolutionProvider
UnknownValidationSolutionProvider
MissingMixManifestSolutionProvider
MissingViteManifestSolutionProvider
MissingLivewireComponentSolutionProvider
UndefinedViewVariableSolutionProvider
GenericLaravelExceptionSolutionProvider
OpenAiSolutionProvider
SailNetworkSolutionProvider
UnknownMysql8CollationSolutionProvider
UnknownMariadbCollationSolutionProvider
It is possible to use your own set of solution providers as such:
$config->collectSolutions([
BadMethodCallSolutionProvider::class,
MyCustomSolutionProvider::class,
]);
When you want to extend the default set of solution providers, you can do the following:
$config->collectSolutions([
...FlareConfig::defaultSolutionProviders(),
MyCustomSolutionProvider::class,
]);
An external package can append its own solution provider to the already constructed Flare instance as such:
Flare::withSolutionProvider(
MyCustomSolutionProvider::class,
);
Adding solutions to exceptions
To add a solution text to your exception, let the exception implement the Spatie\ErrorSolutions\Contracts\ProvidesSolution
interface.
This is what that interface looks like:
namespace Spatie\ErrorSolutions\Contracts;
interface ProvidesSolution
{
public function getSolution(): Solution;
}
The getSolution
method expects you to return an implementation of the Solution
interface. You can create a custom class that implements that interface or use the built-in BaseSolution
class to quickly return a textual solution.
Here's an example of an implementation in a custom exception class:
namespace App\Exceptions;
use Exception;
use Spatie\ErrorSolutions\Contracts\BaseSolution;
use Spatie\ErrorSolutions\Contracts\ProvidesSolution;
use Spatie\ErrorSolutions\Contracts\Solution;
class MyException extends Exception implements ProvidesSolution
{
public function getSolution(): Solution
{
return BaseSolution::create('My solution title')
->setSolutionDescription('My solution description')
->setDocumentationLinks([
'My docs' => 'https://flareapp.io/docs',
]);
}
}
Using solution providers
You can create a solution provider instead of directly adding solutions to exceptions. While exceptions that return a solution provide the solution directly to Flare, a solution provider allows you to determine whether an exception can be solved.
For example, you could create a custom "Stack Overflow solution provider" that will check if a solution can be found for a given throwable.
Solution providers can be added by third-party packages or within your own application.
A solution provider is any class that implements the Spatie\ErrorSolutions\Contracts\HasSolutionsForThrowable
interface.
This is how the interface looks like:
interface HasSolutionsForThrowable
{
public function canSolve(Throwable $throwable): bool;
/** \Facade\IgnitionContracts\Solution[] */
public function getSolutions(Throwable $throwable): array;
}
When an error occurs in your app, the class will receive the Throwable
in the canSolve
method. In that method, you can decide if your solution provider applies to the Throwable
passed. If you return true
, getSolutions
will get called.
Tips on writing clear solutions
When writing custom solutions, make sure that the text that your solution provides is helpful to the user reading it.
For all solutions built into Flare, we use a solution "style guide". You may want to use them in your solutions, too.
Solution title
The solution title should be a complete sentence with the "problem" this solution is trying to fix upfront. It should not contain any punctuation and no caps on all words.
Example:
App Key Missing
Your app key is missing
Solution description
Avoid questions in your solution descriptions. If you are in doubt that your solutions are going to fix the problem 100% of the time, use verbs like "seems", "might", "could", etc. Optionally, state the problem in complete sentences and give clear instructions on how the user can solve it.
You can use markdown inside your solution description to highlight inline-code snippets and point to files or classes.
Example:
Is your application key missing? Try adding it to your environment variables.
Generate your application encryption key using php artisan key:generate
.
Solution links
In addition to a solution title and description, you can also point the user to various links where the user can read more about how the issue can be fixed or avoided. When linking to external resources, try to be as specific as possible, where the link will take the user.
Example:
Laracasts
Watch "Laravel 12 Fundamentals - Migrations" on Laracasts
AI-powered solutions
To generate AI-powered solutions, you must first install this optional dependency.
composer require openai-php/client
To start sending your errors to OpenAI, you must add the OpenAiSolutionProvider
to your solution providers in the flare.php
config file:
use Spatie\ErrorSolutions\SolutionProviders\Laravel\OpenAiSolutionProvider;
use Spatie\LaravelFlare\FlareConfig;
'collects' => FlareConfig::defaultCollects(
extra: [
CollectType::Solutions->value => [
'solution_providers' => [
...FlareConfig::defaultSolutionProviders(),
OpenAiSolutionProvider::class,
],
],
]
),
The constructor expects an OpenAI API key to be passed; you should generate this key at OpenAI and add it to the error-solutions.php
config file:
return [
'open_ai_key' => 'Your key'
];
By default, the solution provider will send these bits of info to OpenAI:
- The error message
- The error class
- The stack frame
- Other small bits of info on the context surrounding your error
It will not send the request payload or any environment variables to avoid sending sensitive data to OpenAI.
Caching requests to AI
By default, all errors sent will be cached for 60 seconds.
Setting the AI model
In the error-solutions.php
config file, you can set the AI model to generate the solutions. By default, the gpt-3.5-turbo
model will be used.
return [
'open_ai_model' => 'gpt-4'
];