code-distortion/清晰度控制

一个用于捕获和记录异常的流畅接口的Laravel包

0.1.0 2023-12-31 07:33 UTC

This package is auto-updated.

Last update: 2024-08-30 01:29:11 UTC


README

Latest Version on Packagist PHP Version Laravel GitHub Workflow Status Buy The World a Tree Contributor Covenant

code-distortion/clarity-control 是一个允许您使用流畅接口捕获和记录异常的Laravel包。

// run $callable - will catch + report() any exceptions
Control::run($callable);

// do the same, but with extra optional configuration
Control::prepare($callable)
    ->channel('slack')
    ->level(Settings::REPORTING_LEVEL_WARNING)
    ->debug() … ->emergency()
    ->default('some-value')
    ->catch(DivisionByZeroError::class)
    ->match('Undefined variable $a')
    ->matchRegex('/^Undefined variable /')
    ->known('https://company.atlassian.net/browse/ISSUE-1234')
    ->report() or ->dontReport()
    ->rethrow() or ->dontRethrow() or ->rethrow($callable)
    ->callback($callable)
    ->finally($callable)
    ->execute();

清晰度套件

清晰度控制是 清晰度套件 的一部分,旨在让您更容易地管理异常。


目录

安装

通过composer安装此包

composer require code-distortion/clarity-control

配置文件

如果您想发布 config/code_distortion.clarity_control.php 配置文件,请使用以下命令

php artisan vendor:publish --provider="CodeDistortion\ClarityControl\ServiceProvider" --tag="config"

捕获异常

清晰度控制处理流程控制。也就是说,它提供了捕获和管理异常的方法。

当然,您仍然可以使用 try / catch 语句,但是您也可以这样编写

use CodeDistortion\ClarityControl\Control;

Control::run($callable);

// is equivalent to:
try {
    $callable(); // … do something
} catch (Exception $e) {
    report($e);
}

控制将运行传递给 Control::run(…)callable。如果发生异常,它将被捕获并使用 Laravel 的 report() 辅助函数报告。

随后的代码将继续运行。

提示: Laravel 的 依赖注入 系统用于运行您的可调用对象。只需指定参数的类型提示,它们就会为您解决。

配置异常捕获方式

另一种编写方式是先调用 Control::prepare($callable),然后执行 ->execute()

use CodeDistortion\ClarityControl\Control;

Control::prepare($callable)->execute();
// is equivalent to:
Control::run($callable);

这些是相同的,只是在调用 Control::prepare($callable)->execute() 时,有机会在中间设置一些配置值...

以下是您可以用来配置控制捕获异常方式的列表(它们在下面有更详细的解释)

use CodeDistortion\ClarityControl\Control;
use CodeDistortion\ClarityControl\Settings;

Control::prepare($callable)
    ->channel('slack')
    ->level(Settings::REPORTING_LEVEL_WARNING)
    ->debug() … ->emergency()
    ->default('default')
    ->catch(DivisionByZeroError::class)
    ->match('Undefined variable $a')
    ->matchRegex('/^Undefined variable /')
    ->known('https://company.atlassian.net/browse/ISSUE-1234')
    ->report() or ->dontReport()
    ->rethrow() or ->dontRethrow() or ->rethrow($callable)
    ->callback($callable)
    ->finally($callable)
    ->execute();

关于日志的注意事项

此包使用 清晰度上下文,并且一些设置需要知道 清晰度上下文(例如 清晰度记录器)的记录器才能工作。具体来说,通道日志级别“已知”问题 设置否则不会出现。

这些详细信息添加到 清晰度上下文 在发生异常时生成的 Context 对象中。并且这取决于记录器使用其值。

有关此 Context 对象的更多信息,请参阅 清晰度上下文

有关理解 Context 对象的记录器,请参阅 清晰度记录器

日志通道

您可以指定您想要记录的 Laravel 日志通道。可能的值来自您的项目的 config/logging.php 文件。

Control::prepare($callable)->channel('slack')->execute();

如果您想的话,可以指定多个。

Control::prepare($callable)->channel(['stack', 'slack'])->execute();

注意:此设置需要一款了解 Clarity 的日志工具。有关更多信息,请参阅关于日志的说明

有关日志通道的更多信息,请参阅Laravel 关于日志的文档

日志级别

您可以在日志时指定希望使用的报告级别。

use CodeDistortion\ClarityControl\Settings;

Control::prepare($callable)->debug()->execute();
Control::prepare($callable)->info()->execute();
Control::prepare($callable)->notice()->execute();
Control::prepare($callable)->warning()->execute();
Control::prepare($callable)->error()->execute();
Control::prepare($callable)->critical()->execute();
Control::prepare($callable)->alert()->execute();
Control::prepare($callable)->emergency()->execute();
// or
Control::prepare($callable)->level(Settings::REPORTING_LEVEL_WARNING)->execute(); // etc

注意:此设置需要一款了解 Clarity 的日志工具。有关更多信息,请参阅关于日志的说明

有关日志级别的更多信息,请参阅Laravel 关于日志的文档

默认返回值

您可以通过向 Control::run()Control::prepare() 传递第二个参数来指定异常发生时返回的默认值。

$result = Control::run($callable, $default);
// or
$result = Control::prepare($callable, $default)->execute();

您也可以在调用 Control::prepare() 后调用 ->default()

$result = Control::prepare($callable)->default($default)->execute();

提示:如果默认值是 callable,Control 将在需要时运行它以解决值。

选择性捕获

您可以选择只捕获某些类型的异常。其他异常将被忽略。

use DivisionByZeroError;

Control::prepare($callable)
    ->catch(DivisionByZeroError::class) // only catch this type of exception
    ->execute();
Control::prepare($callable)
    ->match('Undefined variable $a')       // exact string match of $e->getMessage()
    ->matchRegex('/^Undefined variable /') // regex string match of $e->getMessage()
    ->execute();

您可以指定多个异常类、匹配字符串或正则表达式。

当指定 match()matchRegex() 时,只需其中一个匹配异常消息即可。

记录“已知”问题

如果您使用像 Jira 这样的问题管理系统,您可以记录与异常相关的问题/任务

Control::prepare($callable)
    ->known('https://company.atlassian.net/browse/ISSUE-1234')
    ->execute();

这为您提供了一个在修复正在进行时标记异常的机会。

注意:此设置需要一款了解 Clarity 的日志工具。有关更多信息,请参阅关于日志的说明

禁用日志

一旦捕获到异常,您就可以禁用异常的报告。这将阻止触发 report()

Control::prepare($callable)->dontReport()->execute();
// or
Control::prepare($callable)->report(false)->execute();

重新抛出异常

如果您希望捕获的异常被检测并报告,但在之后再次 重新抛出,您可以告诉 Control 重新抛出它们

Control::prepare($callable)->rethrow()->execute();

如果您希望重新抛出不同的异常,您可以通过传递一个闭包来做出决定。它必须返回一个 Throwable / Exception,或者 true / false。

$closure = fn(Throwable $e) => new MyException('Something happened', 0, $e);
Control::prepare($callable)->rethrow($closure)->execute();

抑制异常

如果您希望在捕获后停止报告和重新抛出异常,您可以完全抑制它们。

Control::prepare($callable)->suppress()->execute();
// is equivalent to:
Control::prepare($callable)->dontReport()->dontRethrow()->execute();

回调

您可以在捕获异常时添加一个自定义回调来运行。这可以用来在发生异常时执行某些操作,或者决定是否抑制异常

如果您愿意,可以添加多个回调。

use CodeDistortion\ClarityControl\Context;
use Illuminate\Http\Request;
use Throwable;

$callback = fn(Throwable $e, Context $context, Request $request) => …; // do something

Control::prepare($callable)->callback($callback)->execute();

提示:使用Laravel 的 依赖注入 来运行您的回调。只需像上面的示例一样类型提示您的参数。

您可以使用的一些额外参数是

  • 异常:当参数名为 $e$exception
  • Context 对象:当使用 CodeDistortion\ClarityContext\Context 类型提示时

在回调中使用上下文对象

当您使用 CodeDistortion\ClarityContext\Context 类型提示回调参数时,您将收到包含有关异常的详细信息的 Context 对象。

这是与Clarity Context 包中的相同的 Context 对象,并设计用于在 app/Exceptions/Handler.php 中报告异常时使用。有关更多信息,请参阅 Clarity Context 的文档

除了从 Context 对象中读取值之外,您还可以在回调中更新其一些值。这允许您动态地更改发生的事情。

use CodeDistortion\ClarityControl\Context;
use CodeDistortion\ClarityControl\Settings;

$callback = function (Context $context) {
    // the exception that occurred
    $context->getException();
    // manage the log channels
    $context->getChannels();
    $context->setChannels(['slack']);
    // manage the log reporting level
    $context->getLevel();
    $context->setLevel(Settings::REPORTING_LEVEL_WARNING);
    $context->debug() … $context->emergency();
    // manage the default return value
    $context->getDefault();
    $context->setDefault('default');
    // manage the request's trace identifiers
    $context->getTraceIdentifiers();
    $context->setTraceIdentifiers([$traceId]);
    // manage the known issues
    $context->hasKnown();
    $context->getKnown();
    $context->setKnown(['https://company.atlassian.net/browse/ISSUE-1234']);
    // manage the report setting
    $context->getReport();
    $context->setReport(true/false);
    $context->dontReport();
    // manage the rethrow setting
    $context->getRethrow();
    $context->setRethrow(true/false);
    $context->setRethrow($exception); // a new exception to rethrow
    $context->setRethrow($callable);  // a closure that decides which exception to rethrow
    $context->dontRethrow();
    // turn both report and rethrow off
    $context->suppress();
};

即时抑制异常

您可以通过在回调中调用 $context->suppress() 来抑制异常。

如果您的回调将 $context->setReport(false)$context->setRethrow(false) 设置为 true,也会发生这种情况。

提示:回调按指定的顺序运行。当异常被抑制时,不会调用后续的回调。

use CodeDistortion\ClarityControl\Context;
use Illuminate\Http\Request;

$callback = function (Context $context, Request $request) {

    // suppress the exception when the user-agent is 'test-agent'
    if ($request->userAgent == 'test-agent') {
        $context->suppress()
        // or
        $context->setReport(false)->setRethrow(false);
    }
};

Control::prepare($callable)->callback($callback)->execute();

全局回调

您可以让控制台在捕获到异常时运行一个“全局”回调。您可以添加任意多个。

这些回调会在常规(非全局)回调之前运行。

Control::globalCallback($callable);

在服务提供者中设置一个是个不错的选择。有关服务提供者的更多信息,请参阅Laravel的文档:更多关于服务提供者的信息

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use CodeDistortion\ClarityControl\Control;

class MyServiceProvider extends ServiceProvider
{
    public function boot()
    {
        $callback = function () { … }; // do something
        Control::globalCallback($callback); // <<<
    }
}

最后

您可以通过将第三个参数传递给Control::run()Control::prepare()来指定在执行主$callable之后运行的调用。

$finally = fn() => …; // do something

Control::run($callable, 'default', $finally);
// or
Control::prepare($callable, 'default', $finally)->execute();

在调用Control::prepare()之后,您还可以调用->finally()

Control::prepare($callable)->finally($finally)->execute();

提示: Laravel 的 依赖注入 系统用于运行您的可调用对象。只需指定参数的类型提示,它们就会为您解决。

高级捕获

您可以选择在捕获到不同异常时执行不同的操作。

为此,配置一个CodeDistortion\ClarityControl\CatchType对象,并将其传递给$clarity->catch()而不是传递异常类字符串

CatchType对象可以使用与Control对象相同的设置进行自定义。它们都是可选的,可以按任意顺序调用。

use CodeDistortion\ClarityControl\CatchType;
use CodeDistortion\ClarityControl\Settings;

$catchType1 = CatchType::channel('slack')
    ->level(Settings::REPORTING_LEVEL_WARNING)
    ->debug() … ->emergency()
    ->default('default')
    ->catch(DivisionByZeroError::class)
    ->match('Undefined variable $a')
    ->matchRegex('/^Undefined variable /')
    ->known('https://company.atlassian.net/browse/ISSUE-1234')
    ->report() or ->dontReport()
    ->rethrow() or ->dontRethrow() or ->rethrow($callable)
    ->suppress()
    ->callback($callable)
    ->finally($callable);
$catchType2 = …;

Control::prepare($callable)
    ->catch($catchType1)
    ->catch($catchType2)
    ->execute();

CatchTypes将按指定的顺序进行检查。第一个匹配异常的将被使用。

检索异常

如果您想获取异常,可以调用getException()并通过引用传递一个变量。当发生异常时,它将包含异常。否则,它设置为null

即使异常被抑制,也会设置异常。

Control::prepare($callable)->getException($e)->execute();

dump($e); // will contain the exception, or null

测试此包

  • 克隆此包:git clone https://github.com/code-distortion/clarity-control.git .
  • 运行composer install以安装依赖项
  • 运行测试:composer test

变更日志

请参阅CHANGELOG以获取最近更改的更多信息。

语义版本

此库使用SemVer 2.0.0版本控制。这意味着对X的改变表示破坏性更改:0.0.X0.X.yX.y.z。当此库更改为版本1.0.0、2.0.0等时,这并不一定表示是一个显著的版本发布,它仅表示更改是破坏性的。

实物捐赠

此包是Treeware。如果您在生产环境中使用它,那么我们要求您为我们购买一棵树以感谢我们的工作。通过为Treeware森林做出贡献,您将为当地家庭创造就业机会并恢复野生动物栖息地。

贡献

请参阅CONTRIBUTING以获取详细信息。

行为准则

请参阅CODE_OF_CONDUCT以获取详细信息。

安全性

如果您发现任何安全相关的问题,请通过电子邮件tim@code-distortion.net联系,而不是使用问题跟踪器。

鸣谢

许可

MIT许可(MIT)。请参阅许可文件以获取更多信息。