Swoole协程中异常需在协程内用try…catch处理,1. 使用throw抛出异常;2. 必须在协程内捕获,否则可能导致崩溃;3. 异常不跨协程传播,需通过Channel传递错误信息;4. 建议封装safeGo函数统一捕获异常,防止服务不稳定。

在Swoole协程中处理异常,和PHP传统的异常机制基本一致,但需注意协程环境的特殊性。你可以使用 try…catch 捕获异常,也可以通过 throw 主动抛出异常。关键是:协程内的异常不会自动跨协程传播,必须在当前协程内捕获。
1. 在协程内抛出异常
使用 throw new Exception() 即可抛出异常。只要在协程函数内部抛出,就可以被同一协程中的 try…catch 捕获。
异常必须在协程函数内部抛出和处理 不能依赖外层同步代码块捕获协程内部未处理的异常
示例:
go(function () { try { throw new RuntimeException('协程内发生错误'); } catch (RuntimeException $e) { echo '捕获异常: ' . $e->getMessage() . "\n"; }});
2. 捕获协程内部的异常
如果不在协程内部捕获异常,程序可能会崩溃或静默退出(取决于 Swoole 版本和配置)。因此建议所有可能出错的逻辑都包裹在 try…catch 中。
错误示范(异常未被捕获):
go(function () { throw new Exception('这个异常没被捕获');});// 可能导致进程退出或日志报错
正确做法:
火山写作
字节跳动推出的中英文AI写作、语法纠错、智能润色工具,是一款集成创作、润色、纠错、改写、翻译等能力的中英文 AI 写作助手。
167 查看详情
go(function () { try { // 可能出错的操作,如协程客户端调用 $client = new Swoole\Coroutine\Http\Client('httpbin.org', 80); $client->get('/'); if ($client->errCode) { throw new RuntimeException('HTTP请求失败'); } } catch (Throwable $throwable) { // 推荐捕获 Throwable,防止致命错误中断协程 echo '协程内异常: ' . $throwable->getMessage() . "\n"; }});
3. 跨协程异常传递?不行!
每个协程是独立执行单元,父协程无法直接捕获子协程抛出的异常。你必须通过通信机制(如 Channel)传递错误信息。
使用 Channel 传递异常信息:
$chan = new Swoole\Coroutine\Channel(1);go(function () use ($chan) { try { throw new Exception('模拟出错'); } catch (Exception $e) { $chan->push(['error' => $e->getMessage()]); }});$result = $chan->pop();if (isset($result['error'])) { echo '收到错误: ' . $result['error'] . "\n";}
4. 建议:统一捕获避免崩溃
为防止协程因未捕获异常导致服务不稳定,可以封装一个安全的 go 函数:
function safeGo(callable $func) { go(function () use ($func) { try { $func(); } catch (Throwable $throwable) { echo "协程异常未处理: {$throwable->getMessage()}\n"; // 可记录日志或上报监控 } });}// 使用safeGo(function () { throw new Exception('出错了');});
基本上就这些。Swoole协程里抛异常很简单,关键是要在协程自己内部处理好,别让它“裸奔”。
以上就是Swoole协程里怎么抛出和捕获异常的详细内容,更多请关注php中文网其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/801148.html
微信扫一扫
支付宝扫一扫