错误和记录
Introduction
当您第一次开始使用 Winter CMS 时,已经为您配置了错误和异常处理。可以通过两种方式访问事件日志:
- 可以通过打开文件在文件系统中查看事件日志
storage/logs/system.log
. - 或者,可以通过导航到管理区域查看系统 > 日志 > 事件日志.
日志条目总是在显示错误页面时创建,并且对于某些异常类型.
NOTE: 一些服务器错误级别太低,Winter 无法处理,因此仅在发生错误的相关日志中可见。这些通常是服务器配置的问题,您应该在您使用的服务器软件保存日志的任何地方查找这些日志。
Configuration
错误详情
您的应用程序通过浏览器显示的错误详细信息的数量由debug
你的配置选项config/app.php
配置文件。默认情况下详细的错误报告是打开的on 因此,查看详细的错误信息对调试和故障排除很有帮助。关闭此功能后,当页面出现问题时,将显示通用错误消息。
对于本地开发,您应该设置debug
值true
.在您的生产环境中,此值应始终为false
.
/*
|--------------------------------------------------------------------------
| Application Debug Mode
|--------------------------------------------------------------------------
|
| When your application is in debug mode, detailed error messages with
| stack traces will be shown on every error that occurs within your
| application. If disabled, a simple generic error page is shown.
|
*/
'debug' => false,
日志文件模式
Winter支持single
,daily
,syslog
和errorlog
记录模式。例如,如果您希望使用每日日志文件而不是单个文件,您应该简单地设置log
你的价值config/app.php
配置文件:
'log' => 'daily'
可用的例外
Winter 附带了几种开箱即用的基本异常类型。
申请异常
这Winter\Storm\Exception\ApplicationException
类,别名为ApplicationException
, 是在简单应用程序条件失败时使用的最常见的异常类型。
throw new ApplicationException('You must be logged in to do that!');
错误消息将被简化,绝不会包含任何敏感信息,如 php 文件和行号。
系统异常
这Winter\Storm\Exception\SystemException
类,别名为SystemException
, 用于对系统运行至关重要且始终记录的错误。
throw new SystemException('Unable to contact the mail server API');
抛出此异常时,将显示详细的错误消息以及发生该异常的文件和行号。
验证异常
这Winter\Storm\Exception\ValidationException
类,别名为ValidationException
, 用于与表单提交和无效字段直接相关的错误。该消息应包含一个带有字段和错误消息的数组。
throw new ValidationException(['username' => 'Sorry that username is already taken!']);
您还可以传递一个实例验证服务.
$validation = Validator::make(...);
if ($validation->fails()) {
throw new ValidationException($validation);
}
当抛出此异常时AJAX框架 将以可用格式提供此信息并聚焦第一个无效字段。
AJAX 异常
这Winter\Storm\Exception\AjaxException
类,别名为AjaxException
, 被认为是“智能错误”并将返回 HTTP 代码 406。这允许它们传递响应内容,就好像它们是成功响应一样。
throw new AjaxException(['#flashMessages' => $this->renderPartial(...)]);
当抛出此异常时AJAX框架 将遵循标准错误工作流程,但也会刷新指定的部分。
异常处理
所有异常都由Winter\Storm\Foundation\Exception\Handler
班级。这个类包含两个方法:report
和render
指示是否应记录错误以及如何响应错误。
但是,如果需要,您可以使用App::error
方法。处理程序是根据它们处理的异常的类型提示来调用的。例如,您可以创建一个只处理RuntimeException
实例:
App::error(function(RuntimeException $exception) {
// Handle the exception...
});
如果异常处理程序返回一个响应,该响应将被发送到浏览器并且不会调用其他错误处理程序:
App::error(function(InvalidUserException $exception) {
return 'Sorry! Something is wrong with this account!';
});
要侦听 PHP 致命错误,您可以使用App::fatal
方法:
App::fatal(function($exception) {
//
});
如果您有多个异常处理程序,则应按从最通用到最具体的顺序定义它们。因此,例如,处理所有类型异常的处理程序Exception
应该在自定义异常类型之前定义,例如SystemException
.
在哪里放置错误处理程序
错误处理程序注册,例如事件处理器,通常属于“引导代码”类别。换句话说,它们让您的应用程序准备好实际处理请求,并且通常需要在实际调用路由或控制器之前执行。最常见的地方是boot
一个方法插件注册文件.或者,插件可以提供一个名为init.php 在可用于放置错误处理程序注册的插件目录中。
HTTP 异常
一些异常描述来自服务器的 HTTP 错误代码。例如,这可能是“找不到页面”错误 (404)、“未经授权的错误”(401) 甚至是开发人员生成的 500 错误。为了从应用程序的任何地方生成这样的响应,请使用以下命令:
App::abort(404);
这abort
方法将立即引发异常,该异常将由异常处理程序呈现。或者,您可以提供响应文本:
App::abort(403, 'Unauthorized action.');
在请求的生命周期中,可以随时使用此方法。
自定义错误页面
默认情况下,任何错误都将显示一个详细的错误页面,其中包含文件内容、行号和发生错误的堆栈跟踪。您可以通过设置配置值来显示自定义错误页面debug
到false 在里面config/app.php
脚本并使用 URL 创建页面/error
.
Logging
默认情况下,Winter 配置为为您的应用程序创建单个日志文件,该文件存储在storage/logs
目录。您可以使用Log
正面:
$user = User::find(1);
Log::info('Showing user profile for user: '.$user->name);
记录器提供了定义在RFC 5424:emergency
,alert
,critical
,error
,warning
,notice
,info
和debug
.
Log::emergency($error);
Log::alert($error);
Log::critical($error);
Log::error($error);
Log::warning($error);
Log::notice($error);
Log::info($error);
Log::debug($error);
上下文信息
上下文数据数组也可以传递给日志方法。此上下文数据将被格式化并与日志消息一起显示:
Log::info('User failed to login.', ['id' => $user->id]);
辅助函数
有一些全局辅助方法可以使日志记录更容易。这trace_log
函数是一个别名Log::info
支持使用数组和异常作为消息。
// Write a string value
$val = 'Hello world';
trace_log('The value is '.$val);
// Dump an array value
$val = ['Some', 'array', 'data'];
trace_log($val);
// Trace an exception
try {
//
}
catch (Exception $ex) {
trace_log($ex);
}
这trace_sql
函数启用数据库日志记录,调用时它将记录发送到数据库的每个命令。这些记录只出现在system.log
文件并且不会出现在管理区域日志中,因为它存储在数据库中并且会导致反馈循环。
trace_sql();
Db::table('users')->count();
// select count(*) as aggregate from users