snicco / psr7-error-handler
psr7应用的一个强大且可定制的错误处理器。
Requires
- php: ^7.4|^8.0
- psr/http-factory: ^1.0.0
- psr/http-message: ^1.0.0
- psr/log: ^1.1.1
Requires (Dev)
- nyholm/psr7: ^1.0.0
- phpunit/phpunit: ^9.5.13
Conflicts
- snicco/better-wp-api: <2.0.0-beta.9
- snicco/better-wp-cache: <2.0.0-beta.9
- snicco/better-wp-cache-bundle: <2.0.0-beta.9
- snicco/better-wp-cli: <2.0.0-beta.9
- snicco/better-wp-cli-testing: <2.0.0-beta.9
- snicco/better-wp-hooks: <2.0.0-beta.9
- snicco/better-wp-hooks-bundle: <2.0.0-beta.9
- snicco/better-wp-mail: <2.0.0-beta.9
- snicco/better-wp-mail-bundle: <2.0.0-beta.9
- snicco/better-wp-mail-testing: <2.0.0-beta.9
- snicco/better-wpdb: <2.0.0-beta.9
- snicco/better-wpdb-bundle: <2.0.0-beta.9
- snicco/blade-bridge: <2.0.0-beta.9
- snicco/blade-bundle: <2.0.0-beta.9
- snicco/content-negotiation-middleware: <2.0.0-beta.9
- snicco/debug-bundle: <2.0.0-beta.9
- snicco/default-headers-middleware: <2.0.0-beta.9
- snicco/eloquent: <2.0.0-beta.9
- snicco/encryption-bundle: <2.0.0-beta.9
- snicco/event-dispatcher: <2.0.0-beta.9
- snicco/event-dispatcher-testing: <2.0.0-beta.9
- snicco/guests-only-middleware: <1.0.0
- snicco/http-routing: <2.0.0-beta.9
- snicco/http-routing-bundle: <2.0.0-beta.9
- snicco/http-routing-testing: <2.0.0-beta.9
- snicco/https-only-middleware: <2.0.0-beta.9
- snicco/illuminate-container-bridge: <2.0.0-beta.9
- snicco/kernel: <2.0.0-beta.9
- snicco/kernel-testing: <2.0.0-beta.9
- snicco/method-override-middleware: <2.0.0-beta.9
- snicco/minimal-logger: <2.0.0-beta.9
- snicco/must-match-route-middleware: <2.0.0-beta.9
- snicco/no-robots-middleware: <2.0.0-beta.9
- snicco/open-redirect-protection-middleware: <2.0.0-beta.9
- snicco/payload-middleware: <2.0.0-beta.9
- snicco/pimple-bridge: <2.0.0-beta.9
- snicco/redirect-middleware: <2.0.0-beta.9
- snicco/session: <2.0.0-beta.9
- snicco/session-bundle: <2.0.0-beta.9
- snicco/session-psr16-bridge: <2.0.0-beta.9
- snicco/session-testing: <2.0.0-beta.9
- snicco/session-wp-bridge: <2.0.0-beta.9
- snicco/share-cookies-middleware: <2.0.0-beta.9
- snicco/signed-url: <2.0.0-beta.9
- snicco/signed-url-psr15-bridge: <2.0.0-beta.9
- snicco/signed-url-psr16-bridge: <2.0.0-beta.9
- snicco/signed-url-testing: <2.0.0-beta.9
- snicco/signed-url-wp-bridge: <2.0.0-beta.9
- snicco/str-arr: <2.0.0-beta.9
- snicco/templating: <2.0.0-beta.9
- snicco/templating-bundle: <2.0.0-beta.9
- snicco/testable-clock: <2.0.0-beta.9
- snicco/testing-bundle: <2.0.0-beta.9
- snicco/trailing-slash-middleware: <2.0.0-beta.9
- snicco/wp-auth-only-middleware: <2.0.0-beta.9
- snicco/wp-capability-middleware: <2.0.0-beta.9
- snicco/wp-capapility-middleware: <1.0.0
- snicco/wp-guests-only-middleware: <2.0.0-beta.9
- snicco/wp-nonce-middleware: <2.0.0-beta.9
- dev-master
- v2.0.0-beta.9
- v2.0.0-beta.8
- v2.0.0-beta.7
- v2.0.0-beta.6
- v2.0.0-beta.5
- v2.0.0-beta.4
- v2.0.0-beta.3
- v2.0.0-beta.2
- v2.0.0-beta.1
- v1.10.1
- v1.10.0
- v1.9.1
- v1.9.0
- v1.8.1
- v1.8.0
- v1.7.0
- v1.6.2
- v1.6.1
- v1.6.0
- v1.5.0
- v1.4.2
- v1.4.1
- v1.4.0
- v1.3.0
- v1.2.1
- v1.2.0
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1.0
- v1.0.2
- v1.0.1
- v1.0.0
- dev-beta
This package is auto-updated.
Last update: 2024-09-07 14:27:52 UTC
README
Snicco项目(Snicco)的ErrorHandler组件是一个独立的错误处理器,用于使用PSR-7
请求的PHP
应用程序。
目录
安装
composer require snicco/psr7-error-handler
HTTP错误处理器的协作者
在高层,HttpErrorHandler
接口负责将Throwable
实例转换为Psr\Http\Message\ResponseInterface
实例。
此包提供了一个TestErrorHandler
,它只是重新抛出异常,以及一个ProductionErrorHandler
,这是本文档的主要内容。
为了实例化ProductionErrorHandler
,我们需要以下协作者:
RequestAwareLogger
RequestAwareLogger
是一个围绕PSR-3 logger
的简单包装类。
它允许您根据捕获的异常、当前请求等,为每个日志条目添加日志上下文。
RequestAwareLogger::__construct()
传入的最后一个参数是可变参数,接受RequestLogContext
实例。
以下是使用方法
(Monolog只是一个示例,您可以使用任何PSR-3 logger。)
use Psr\Log\LogLevel; use Snicco\Component\Psr7ErrorHandler\Information\ExceptionInformation; use Snicco\Component\Psr7ErrorHandler\Log\RequestAwareLogger; use Snicco\Component\Psr7ErrorHandler\Log\RequestLogContext; $monolog = new Monolog\Logger(); $request_aware_logger = new RequestAwareLogger($monolog); // With custom exception levels. // By default, any status code > 500 will be LogLevel::CRITICAL // Anything below will be LogLevel::ERROR $request_aware_logger = new RequestAwareLogger($monolog, [ Throwable::class => LogLevel::ALERT, MyCustomException::class => LogLevel::WARNING ]) // With custom log context: class AddIPAddressFor403Exception implements RequestLogContext { public function add(array $context, ExceptionInformation $information) : array{ if(403 === $information->statusCode()) { $context['ip'] = $information->serverRequest()->getServerParams()['REMOTE_ADDR']; } return $context; } } // The last argument is variadic. $request_aware_logger = new RequestAwareLogger($monolog, [], new AddIPAddressFor403Exception());
ExceptionInformationProvider
ExceptionInformationProvider
负责将Throwable
实例转换为ExceptionInformation
实例。
ExceptionInformation
是一个值对象,由以下内容组成
- 一个用于异常的唯一标识符,将作为日志上下文传递并显示给用户。
- 在显示异常时应使用的HTTP状态码。
- 一个安全的异常标题,用于显示(安全意味着“不包含敏感信息”)。
- 一个安全的消息,用于显示异常(安全意味着“不包含敏感信息”)。
- 原始的
Throwable
- 转换后的
Throwable
- 原始的
Psr\Http\Message\ServerRequestInterface
实例
此包附带了一个InformationProviderWithTransformation
实现。
您可以如下实例化此类
use Snicco\Component\Psr7ErrorHandler\Identifier\SplHashIdentifier; use Snicco\Component\Psr7ErrorHandler\Information\InformationProviderWithTransformation; // uses spl_object_hash to uniquely identify exceptions. $identifier = new SplHashIdentifier(); // This will use the error messages in /resources/en_US.error.json $information_provider = InformationProviderWithTransformation::fromDefaultData($identifier); // Or with custom error messages $error_messages = [ // The 500 status code is mandatory. All other HTTP status codes are optional. 500 => [ 'title' => 'Whoops, this did not work...', 'message' => 'An error has occurred... We are sorry.' ]; ] $information_provider = new InformationProviderWithTransformation($error_messages, $identifier);
正如其类名所暗示的,InformationProviderWithTransformation
允许您将异常转换为其他类型的异常。
这是通过使用 ExceptionTransformers
来实现的。
以下是如何将自定义异常类转换为 HttpException
实例的示例。
use Snicco\Component\Psr7ErrorHandler\Information\ExceptionTransformer; class CustomAuthenticationTo404Transformer implements ExceptionTransformer { public function transform(Throwable $e) : Throwable{ if(!$e instanceof MyCustomAuthenticationException) { return $e; } // Key value pairs of headers that will later be added to the PSR-7 response. $response_headers = [ 'WWW-Authenticate' => '/login' ]; // The status code that should be used for the PSR-7 response. $status_code = 401; return \Snicco\Component\Psr7ErrorHandler\HttpException::fromPrevious($e, $status_code, $response_headers); } } $identifier = new SplHashIdentifier(); $information_provider = InformationProviderWithTransformation::fromDefaultData( $identifier, new CustomAuthenticationTo404Transformer() // Last argument is variadic );
如果您没有提供任何 ExceptionTransformers
,则每个异常都将转换为状态码为 500
的 HttpException
(除非它已经是 HttpException
的实例)。
ExceptionDisplayer
ExceptionDisplayer
负责显示 ExceptionInformation
。
ExceptionDisplayer
只支持一种内容类型。
ProductionExceptionHandler
接受一个或多个 ExceptionDisplayers
,并将确定当前请求的最佳显示程序。
此软件包附带两个默认显示程序,将用作后备。
FallbackHtmlDisplayer
,用于Accept
标头为text/html
的请求。FallbackJsonDisplayer
,用于Accept
标头为application/json
的请求。
通过使用 DisplayerFilters
来确定异常/请求组合的最佳显示程序。
此软件包默认附带以下过滤器
Delegating
,委派到其他过滤器。CanDisplay
,根据ExceptionDisplayer::canDisplay()
的返回值进行过滤。Verbosity
,根据ExceptionDisplayer::isVerbose()
的返回值以及当前请求的详细程度进行过滤。ContentType
,根据ExceptionDisplayer::supportedContentType()
的返回值以及当前请求的Accept
标头进行过滤。! 重要:此过滤器仅执行非常基本的内容协商。内容协商超出了此软件包的范围,应在中间件中执行。
完整工作示例
以下是如何实例化 ProductionErrorHandler
的示例,最好是在您的依赖注入容器中。
use Psr\Log\LogLevel; use Snicco\Component\Psr7ErrorHandler\DisplayerFilter\CanDisplay; use Snicco\Component\Psr7ErrorHandler\DisplayerFilter\ContentType; use Snicco\Component\Psr7ErrorHandler\DisplayerFilter\Delegating; use Snicco\Component\Psr7ErrorHandler\DisplayerFilter\Verbosity; use Snicco\Component\Psr7ErrorHandler\Identifier\SplHashIdentifier; use Snicco\Component\Psr7ErrorHandler\Information\InformationProviderWithTransformation; use Snicco\Component\Psr7ErrorHandler\Log\RequestAwareLogger; use Snicco\Component\Psr7ErrorHandler\ProductionErrorHandler; // Use any PSR-7 response factory $psr_7_response_factory = new Nyholm\Psr7\Factory\Psr17Factory(); $request_aware_logger = new RequestAwareLogger( new Monolog\Logger(), // Use any PSR-3 logger ); $information_provider = InformationProviderWithTransformation::fromDefaultData( new SplHashIdentifier() ); $prefer_verbose = (bool) getenv('APP_DEBUG'); $displayer_filter = new Delegating( new ContentType(), new Verbosity($prefer_verbose), new CanDisplay(), ); $error_handler = new ProductionErrorHandler( $psr_7_response_factory, $request_aware_logger, $information_provider, $displayer_filter, // Custom exception displayers go here (variadic) )
然后使用实例化的错误处理器,如下所示:
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; use Psr\Http\Server\MiddlewareInterface; use Snicco\Component\Psr7ErrorHandler\HttpErrorHandler; class ErrorHandlerMiddleware implements MiddlewareInterface { private HttpErrorHandler $error_handler; public function __construct(HttpErrorHandler $error_handler) { $this->error_handler = $error_handler; } public function process(ServerRequestInterface $request,RequestHandlerInterface $handler) : ResponseInterface{ try { return $handler->handle($request); }catch (Throwable $e) { return $this->error_handler->handle($e, $request); } } }
异常工具
面向用户的异常
此包附带一个UserFacing
接口,您的自定义异常可以实现该接口。
如果抛出一个实现UserFacing
的异常,将使用UserFacing::safeTitle()
和UserFacing::safeMessage()
的返回值来创建ExceptionInformation
,而不是默认的HTTP错误消息,这些消息可能对用户来说没有意义。
原始异常消息将被记录,而您的用户将看到他们可以相关联的东西(稍微多一点)。
HTTP异常
此包附带一个通用的HTTPException
类,您可以在您的HTTP相关代码中抛出(主要是中间件)。
这允许您指定HTTP响应代码,以及可选的附加响应头。
使用HTTPException
类和使用ExceptionTransformer
之间的区别在于,后者旨在用于您的领域异常,而HTTPExceptions
应该只在HTTP相关代码(如中间件和控制器)中抛出。
贡献
此存储库是Snicco项目开发存储库的只读拆分。
报告问题和发送拉取请求
请将问题报告在Snicco单体存储库中。
安全
如果您发现安全漏洞,请遵循我们的披露程序。