点击上方“Lemon黄”关注我哦,不定期原创文,定期好技术文推广分享

来源地址:https://freek.dev/1441-ignition-a-new-error-page-for-laravel
译文地址:https://learnku.com/laravel/t/33857
在这篇博客文章中,我将告诉你关于 Ignition 的一切。
让我们看看默认情况下 PHP 中有什么。在不使用框架的情况下,PHP 提供了这个功能。您只会得到错误:没有堆栈跟踪、没有请求或应用程序详情。

Symfony 的错误页面稍微好一些,它向您显示堆栈跟踪,但是没有多大帮助。

下面的截图是 Whoops,这是 Laravel 5 中的标准。它比默认的 Symfony 好得多,可以显示堆栈跟踪和一些关于请求的信息。尽管在 Laravel 中 Whoops 是默认值,但它是一个框架无关的(错误收集展示)。它仅仅显示通用信息。

这是 Ignition 的截图,我们建立的新的错误视图。因为这是 Laravel 特有的,我们可以做很多很酷的事情。

如果视图中有错误,这就是 whoops 显示它们的方式。注意,异常消息不适合分配的空间。你必须(鼠标)悬停在它上面才能看完整(信息)。在堆栈跟踪中,您可以看到使用了编译后的 Blade 视图和内容。这使得跟踪哪个 Blade 视图文件包含错误变得困难,并且视图内容本身是不可读的。

Ignition 是一个 Laravel 特定的错误页面。因此,它可以像钩子一样,"挂载" 到框架中,用来显示未编译的视图路径和您的 Blade 视图。顶部还有足够的空间显示整个异常页面,不需要额外的单击。我们也只在默认情况下显示应用程序帧,因为这些可能是您感兴趣的帧。

如果您单击 stack trace选项卡右侧文件名旁边的铅笔图标,我们将在您喜欢的编辑器中自动打开该文件。默认情况下是 PhpStorm 。您可以在 ignition配置文件中将其配置为您最喜欢的编辑器。
注意到右上角的那个小 “望远镜” 链接了吗?我们只会在您安装了 Laravel Telescope(第一方调试助手) 的情况下显示。如果你点击那个链接,你将被带到望远镜内发生错误的异常。

Ignition 选项卡
让我们探索一下 Ignition 页面上显示的选项卡。

在「堆栈跟踪」选项卡旁边,您将看到「请求」选项卡。它显示了您对请求的所有预期信息。
假设你有一个路由定义是这样的::
Route::get('/posts/{post}', function (Post $post) {
//
});
当此路由发生异常,我们将在 Ignition 中打印 路由参数 post 模型($post 变量),以转化后数组(toArray )形式呈现。对于不需要任何绑定的 “简单” 路由参数也是如此。这是一个很好的方法,可以很容易地看到 Laravel 为这个特定的路由接收了什么信息。
在路由参数之后,我们还将向您显示在此请求中使用的中间件列表。
接下来是 “视图” 部分。如果异常发生在视图中,我们将在这里显示视图名称。甚至:我们还将给出传递给视图的所有数据的列表。

"用户" 选项卡包含有使用应用程序的用户和浏览器的更多信息。

在 Context 选项卡中,我们显示关于您的 repo (repo 位于何处,签出提交 hash) 和环境 (您使用的 PHP 和 Laravel 的哪个版本) 的信息。

在 Debug选项卡中,我们将显示异常发生之前发生的事情。比如查询、日志和转储。在转储旁边,我们还显示您将 dump语句放在何处的文件名。单击铅笔图标,您就可以直接访问该文件,并在您最喜欢的编辑器中纠正行号。
所以,Ignition 在看到异常是关于一个没有找到的 Class 时。它将尝试找出在其他命名空间中是否存在这个 Class。如果存在的话,它会建议我们导入。

Ignition 自带一系列常见问题的解决方案。若没有找到 Blade 视图,会采用一个无效视图如下所示。

您还可以自定义异常解决方案。需要异常类实现 Facade\IgnitionContracts\ProvidesSolutions 接口。它要求您添加一个 getSolution方法。下面是一个可能的实现。
namespace App\Exceptions;
use Exception;
use Facade\IgnitionContracts\Solution;
use Facade\IgnitionContracts\BaseSolution;
use Facade\IgnitionContracts\ProvidesSolution;
class CustomException extends Exception implements ProvidesSolution
{
public function getSolution(): Solution
{
return BaseSolution::create("You're doing it wrong")
->setSolutionDescription('You are obviously doing something wrong. Check your code and try again.')
->setDocumentationLinks([
'Laracasts' => 'https://laracasts.com',
'Use Flare' => 'https://flareapp.io',
]);
}
}
下面是在 Ignition 中抛出异常的样子。

运行解决方案
除了仅仅是建议的解决方案,我们也可以运行它们。想象一下,例如,您忘记设置 app key。这是用 Ignition 展示错误的样子。

如果你点击 “生成 app key” 按钮,我们会在后台生成并设置app key。

刷新页面后,应用程序将正常工作 (除非它含有其他异常)
您可以通过让异常实现 Facade\IgnitionContracts\ProvidesSolution 来创建可运行的解决方案,这与不可运行的解决方案非常相似)。getSolution方法既可以返回可运行的解决方案,也可以返回不可运行的解决方案。
namespace App\Exceptions;
use Exception;
use Facade\IgnitionContracts\ProvidesSolution;
class CustomException extends Exception implements ProvidesSolution
{
public function getSolution(): Solution
{
return new MyRunnableSolution();
}
}
下面是实现类 MyRunnableSolution. 示例
namespace App\Solutions;
use Facade\IgnitionContracts\RunnableSolution;
class MyRunnableSolution implements RunnableSolution
{
public function getSolutionTitle(): string
{
return 'You are doing it wrong';
}
public function getSolutionDescription(): string
{
return 'You are doing something wrong, but we can fix it for you.';
}
public function getDocumentationLinks(): array
{
return [];
}
public function getSolutionActionDescription(): string
{
return 'To fix this issue, all you need to do is press the button below.';
}
public function getRunButtonText(): string
{
return 'Fix this for me';
}
public function run(array $parameters = [])
{
// Your solution implementation
}
public function getRunParameters(): array
{
return [];
}
}
以下是在 Ignition 中 如何抛出自定义异常 CustomException 的样子.

当用户点击Fix this for me 修复按钮时,run函数将执行。
您可以将参数从异常发生的请求传递到将运行解决方案的请求。让 getRunParameters返回一个数组。该数组将被传递给 run。
因此,你有能力使用文本或者可运行的解决方案来增强自己的异常。但有时需要为内置的 PHP 异常,甚至是你无法控制代码的第三方异常提供友好的解决方案。
我们允许你使用 "Solution Providers" 来处理上面提到的难点。Solution Providers 是可以通过 Ignition 挂钩到解决方案查找过程的类。当异常被抛出并且 Ignition 接收到异常时,你可以调用自定义 solution provider 为这个异常返回一个或多个可能的解决方案。
例如,您可以创建一个自定义 “堆栈溢出” 解决方案提供程序,它将尝试为给定的异常找到匹配的堆栈溢出结果,并将它们作为解决方案返回。
我们也在 Ignition 自身上使用解决方案提供者。下面是这样一个解决方案提供者的样子:
use Throwable;
use RuntimeException;
use Facade\IgnitionContracts\Solution;
use Facade\Ignition\Solutions\GenerateAppKeySolution;
use Facade\IgnitionContracts\HasSolutionForThrowable;
class MissingAppKeySolutionProvider implements HasSolutionForThrowable
{
public function canSolve(Throwable $throwable): bool
{
if (! $throwable instanceof RuntimeException) {
return false;
}
return $throwable->getMessage() === 'No application encryption key has been specified.';
}
public function getSolutions(Throwable $throwable): array
{
return [
new GenerateAppKeySolution()
];
}
}
这些解决方案提供者可以在 Ignition 中自动注册,如下所示:
namespace App\Providers;
use App\Solutions\GenerateAppKeySolution;
use Facade\IgnitionContracts\SolutionProviderRepository;
use Illuminate\Support\ServiceProvider;
class YourServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* [@return](https://learnku.com/users/31554) void
*/
public function register(SolutionProviderRepository $solutionProviderRepository)
{
$solutionProviderRepository->registerSolutionProvider(GenerateAppKeySolution::class);
}
}
就像这样,方案提供者将继续增强 Ignitions 功能,为您的异常提供解决方案,我们迫不及待地想看看社区将提供什么!
Ignition 具有可扩展性。您可以添加新选项卡或替换默认选项卡。
让我们看一下提供的 facade/ignition-tinker-tab。该包是一个基于 spatie/laravel-web-tinker 的包装器,它允许您在浏览器中使用 Artisan tinker。
安装了 facade/ignition-tinker-tab,您就可以在错误页面上使用 Artisan tinker。

我们还创建了第二个包,名为 facade/ignition-code-editor。这个选项卡替换了默认的 stack trace 选项卡,使用一个自定义选项卡,允许您在错误屏幕上编辑代码。它就在如下操作。

想学习如何添加自定义选项卡,请访问the documentation on adding tabs.