You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ReactPHP Browser的Promise中链式处理多种异常类型?

ReactPHP Promise 多异常类型优雅处理方案

ReactPHP 原生 Promise 的 then/otherwise 方法不支持直接链式添加多个失败处理函数并自动匹配异常类型,但可以通过自定义异常匹配逻辑+Promise链式调用实现类似 try-catch 多类型捕获的效果。

方案一:自定义catchType工具函数(推荐)

封装一个工具函数,专门用来匹配指定类型的异常,实现语义化的多异常处理:

/**
 * 创建针对特定异常类型的处理函数
 * @param string $type 目标异常类名(支持继承关系)
 * @param callable $handler 匹配成功后的处理逻辑
 * @return callable
 */
function catchType(string $type, callable $handler): callable
{
    return function (\Throwable $e) use ($type, $handler) {
        if ($e instanceof $type) {
            return $handler($e);
        }
        // 非目标类型,重新抛出异常交给后续处理
        throw $e;
    };
}

使用示例:

use Psr\Http\Message\ResponseInterface;
use React\Http\Message\ResponseException;

$browser->post($uri, $headers, $body)
    ->then(function (ResponseInterface $response) {
        // 处理正常响应
        var_dump((string)$response->getBody());
    })
    // 优先处理ResponseException类型异常
    ->otherwise(catchType(ResponseException::class, function (ResponseException $e) {
        echo '响应异常: 状态码' . $e->getResponse()->getStatusCode() . PHP_EOL;
    }))
    // 处理其他所有未匹配的异常/错误
    ->otherwise(function (\Throwable $e) {
        echo '系统错误: ' . $e->getMessage() . PHP_EOL;
    });

原理:otherwise会接收前序未被处理的异常,若当前catchType不匹配目标类型,则重新抛出异常,流转到下一个otherwise处理,完全模拟try-catch的顺序匹配逻辑。

方案二:链式then手动分发异常

利用Promise链式调用的特性,在每个then的失败回调中处理特定异常,不匹配则抛出给后续处理:

use Psr\Http\Message\ResponseInterface;
use React\Http\Message\ResponseException;

$browser->post($uri, $headers, $body)
    ->then(
        function (ResponseInterface $response) {
            // 处理正常响应
            var_dump((string)$response->getBody());
        },
        function (\Throwable $e) {
            if ($e instanceof ResponseException) {
                // 处理ResponseException
                echo '响应异常: 状态码' . $e->getResponse()->getStatusCode() . PHP_EOL;
            } else {
                // 非目标类型,抛出给下一个then处理
                throw $e;
            }
        }
    )
    ->then(null, function (\Throwable $e) {
        // 处理其他所有异常/错误
        echo '系统错误: ' . $e->getMessage() . PHP_EOL;
    });

注意事项

  • 优先使用\Throwable代替\Exception,覆盖PHP7+的错误类型(如致命错误、解析错误等)
  • 异常处理顺序需遵循从具体到通用,先捕获子类异常,再捕获父类/通用异常,避免被提前拦截

内容的提问来源于stack exchange,提问作者Xavi Montero

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 04:40:13