# 错误处理中间件
Things go wrong. You can’t predict errors, but you can anticipate them. Each Slim Framework application has an error handler that receives all uncaught PHP exceptions. This error handler also receives the current HTTP request and response objects, too. The error handler must prepare and return an appropriate Response object to be returned to the HTTP client.
> 事情出错。
>
> 你不能预测错误,但你可以预测它们。
>
> 每个Slim 框架应用程序都有一个接收所有未捕获的PHP异常的错误处理程序。
>
> 这个错误处理程序也接收当前的HTTP请求和响应对象。
>
> 错误处理程序必须准备并返回要返回给HTTP客户机的适当响应对象。
## Usage
~~~php
<?php
use Slim\Factory\AppFactory;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
/*
* 应该比ErrorMiddleware更早地添加路由中间件
* 否则,从中抛出的异常将不会由中间件处理
* The routing middleware should be added earlier than the ErrorMiddleware
* Otherwise exceptions thrown from it will not be handled by the middleware
*/
$app->addRoutingMiddleware();
/*
* @param bool $displayErrorDetails -> Should be set to false in production 在生产中应该设置为false
* @param bool $logErrors -> Parameter is passed to the default ErrorHandler 参数传递给默认的ErrorHandler
* @param bool $logErrorDetails -> Display error details in error log 在错误日志中显示错误细节
* which can be replaced by a callable of your choice.
* 它可以由您选择的可调用项来替换。
* Note: This middleware should be added last. It will not handle any exceptions/errors
* 注意:这个中间件应该最后添加。它不会处理任何异常/错误
* for middleware added after it.
* 用于在它之后添加的中间件。
*/
$errorMiddleware = $app->addErrorMiddleware(true, true, true);
// ...
$app->run();
~~~
## 添加自定义错误处理程序
> 您现在可以为任何类型的异常或Throwable映射自定义处理程序。
You can now map custom handlers for any type of Exception or Throwable.
~~~php
<?php
use Psr\Http\Message\ServerRequestInterface;
use Slim\Factory\AppFactory;
use Slim\Psr7\Response;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
// Add Routing Middleware添加路由中间件
$app->addRoutingMiddleware();
// Define Custom Error Handler定义自定义错误处理程序
$customErrorHandler = function (
ServerRequestInterface $request,
Throwable $exception,
bool $displayErrorDetails,
bool $logErrors,
bool $logErrorDetails
) use ($app) {
$payload = ['error' => $exception->getMessage()];
$response = $app->getResponseFactory()->createResponse();
$response->getBody()->write(
json_encode($payload, JSON_UNESCAPED_UNICODE)
);
return $response;
};
// Add Error Middleware添加错误中间件
$errorMiddleware = $app->addErrorMiddleware(true, true, true);
$errorMiddleware->setDefaultErrorHandler($customErrorHandler);
// ...
$app->run();
~~~
## Error Logging错误日志
If you would like to pipe in custom error logging to the default`ErrorHandler`that ships with Slim you can simply extend it and stub the`logError()`method.
> 如果您希望将自定义错误日志传输到Slim附带的默认`errorhandler`,您可以简单地扩展它并存根` logerror()`方法。
~~~php
<?php
namespace MyApp\Handlers;
use Slim\Handlers\ErrorHandler;
class MyErrorHandler extends ErrorHandler
{
protected function logError(string $error): void
{
// Insert custom error logging function.插入自定义错误日志记录功能。
}
}
~~~
~~~php
<?php
use MyApp\Handlers\MyErrorHandler;
use Slim\Factory\AppFactory;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
// Add Routing Middleware添加路由中间件
$app->addRoutingMiddleware();
// Instantiate Your Custom Error Handler实例化自定义错误处理程序
$myErrorHandler = new MyErrorHandler($app->getCallableResolver(), $app->getResponseFactory());
// Add Error Middleware添加错误中间件
$errorMiddleware = $app->addErrorMiddleware(true, true, true);
$errorMiddleware->setDefaultErrorHandler($myErrorHandler);
// ...
$app->run();
~~~
## Error Handling/Rendering
## 错误处理/渲染
The rendering is finally decoupled from the handling. It will still detect the content-type and render things appropriately with the help of`ErrorRenderers`. The core`ErrorHandler`extends the`AbstractErrorHandler`class which has been completely refactored. By default it will call the appropriate`ErrorRenderer`for the supported content types. The core`ErrorHandler`defines renderers for the following content types:
> 渲染最终从处理中解耦出来。
> 它仍然会检测内容类型,并在`ErrorRenderers`的帮助下适当地呈现内容。
> 核心的`ErrorHandler`扩展了已经完全重构的`AbstractErrorHandler`类。
> 默认情况下,它会为支持的内容类型调用适当的`ErrorRenderer `。
> 核心`ErrorHandler`定义了以下内容类型的渲染器:
* `application/json`
* `application/xml`and`text/xml`
* `text/html`
* `text/plain`
For any content type you can register your own error renderer. So first define a new error renderer that implements`\Slim\Interfaces\ErrorRendererInterface`.
> 对于任何内容类型,您都可以注册自己的错误渲染程序。因此,首先定义一个新的错误渲染,它实现了`\Slim\Interfaces\ErrorRendererInterface`。
~~~php
<?php
use Slim\Interfaces\ErrorRendererInterface;
class MyCustomErrorRenderer implements ErrorRendererInterface
{
public function __invoke(Throwable $exception, bool $displayErrorDetails): string
{
return 'My awesome format';
}
}
~~~
And then register that error renderer in the core error handler. In the example below we will register the renderer to be used for`text/html`content types.
> 然后将错误渲染注册到核心错误处理程序中。在下面的例子中,我们将注册用于`text/html`内容类型的渲染 。
~~~php
<?php
use MyApp\Handlers\MyErrorHandler;
use Slim\Factory\AppFactory;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
//
// Add Routing Middleware添加路由中间件
$app->addRoutingMiddleware();
//
// Add Error Middleware添加错误中间件
$errorMiddleware = $app->addErrorMiddleware(true, true, true);
//获取默认的错误处理程序并注册我的自定义错误渲染 。
// Get the default error handler and register my custom error renderer.
$errorHandler = $errorMiddleware->getDefaultErrorHandler();
$errorHandler->registerErrorRenderer('text/html', MyCustomErrorRenderer::class);
// ...
$app->run();
~~~
### Force a specific content type for error rendering 为错误呈现强制指定内容类型
By default, the error handler tries to detect the error renderer using the`Accept`header of the request. If you need to force the error handler to use a specific error renderer you can write the following.
默认情况下,错误处理程序尝试使用请求的`Accept`报头检测错误渲染程序。如果需要强制错误处理程序使用特定的错误渲染程序,可以编写以下代码。
~~~php
$errorHandler->forceContentType('application/json');
~~~
## New HTTP Exceptions 新的HTTP异常
We have added named HTTP exceptions within the application. These exceptions work nicely with the native renderers. They can each have a`description`and`title`attribute as well to provide a bit more insight when the native HTML renderer is invoked.
> 我们已经在应用程序中添加了命名的HTTP异常。这些异常与本地渲染程序配合得很好。它们都可以有一个`description`和`title`属性,以便在调用本地HTML渲染程序时提供更多的信息。
The base class`HttpSpecializedException`extends`Exception`and comes with the following sub classes:
> 基类`HttpSpecializedException`扩展了`Exception`,并附带了以下子类:
* HttpBadRequestException
* HttpForbiddenException
* HttpInternalServerErrorException
* HttpNotAllowedException
* HttpNotFoundException
* HttpNotImplementedException
* HttpUnauthorizedException
You can extend the`HttpSpecializedException`class if they need any other response codes that we decide not to provide with the base repository. Example if you wanted a 504 gateway timeout exception that behaves like the native ones you would do the following:
> 如果他们需要我们决定不提供的其他响应代码,您可以扩展`httpspecializedexception`类。举个例子,如果你想要一个504网关超时异常,它的行为和本地的一样,你可以做以下事情:
~~~php
class HttpForbiddenException extends HttpException
{
protected $code = 504;
protected $message = 'Gateway Timeout.';
protected $title = '504 Gateway Timeout';
protected $description = 'Timed out before receiving response from the upstream server.';
}
~~~
- 开始
- 安装
- 升级指南
- Web服务器
- 概念
- 生命周期
- PSR 7
- 中间件
- 依赖容器
- 实例 及通知和警告处理
- Request
- 请求方法
- 请求头信息
- 请求主体
- 上传的文件
- 请求帮助
- 路由对象
- Response
- 响应状态
- 响应标头
- 响应体
- 返回JSON
- 视图模板
- 路由
- 创建路由
- 路由回调
- 路由策略
- 路线占位符
- 路由名
- 路由组
- 路由中间件
- 路由表达式缓存
- 容器识别解析
- 封装中间件
- 路由的中间件
- 错误处理中间件
- 方法重写的中间件
- 输出缓冲中间件
- 内容长度中间件
- 扩展功能
- 以 / 结尾的路由模式
- 获取当前路由
- 设置CORS
- 使用POST表单上传文件
- 第三方组件
- slim-session
- auth
- slim-api-skeleton
- dir