不能直接捕获——ai sdk 的 e_warning 可被 set_error_handler 拦截,但常因 @ 抑制、sdk 自覆写 handler 或异步上下文而失效;需禁用@、保存/恢复 handler、封装底层函数或改用异常模式 sdk。

set_error_handler 能捕获 AI SDK 的 warning 吗?
不能直接捕获——AI SDK(比如 OpenAI、Qwen、Minimax 的 PHP SDK)抛出的 E_WARNING 可以被 set_error_handler 拦截,但前提是这些警告**没被 try/catch 吞掉**,也没被 @ 抑制。很多 SDK 内部用了 @file_get_contents 或 @curl_exec,这类警告一上来就被屏蔽了,set_error_handler 根本收不到。
为什么 SDK 的 warning 看不见?
常见原因有三个:
- SDK 代码里写了
@运算符(比如@json_decode($raw)),PHP 规定此时set_error_handler不触发 - SDK 自己注册了错误处理器并没透传,比如调用
set_error_handler后又没调用restore_error_handler() - 警告发生在异步上下文(如
pcntl_fork子进程)或 CLI SAPI 的非主执行线程中,错误处理器不生效
怎么让 AI SDK 的 warning 实际被捕获?
得从 SDK 使用层主动“松绑”:
- 禁用
@:不要用@$client->chat()->create(...),改用原生 error_reporting 控制,例如开头加error_reporting(E_ALL & ~E_NOTICE) - 检查 SDK 是否重置了 handler:调用前先保存当前 handler:
$prev = set_error_handler(function($e, $m) { /* your logic */ });,调用后尽快restore_error_handler() - 对关键函数做 wrapper:比如把
curl_exec替换为自定义版本,在返回 false 前手动触发trigger_error('cURL failed', E_WARNING) - 改用异常模式:优先选择支持
throw异常的 SDK 版本(如官方 openai/openai-php v0.8+ 默认抛OpenAI\Responses\Chat\CreateResponseException),而不是依赖 warning
一个能真正捕获 warning 的最小验证示例
别用 SDK,先确认机制可行:
set_error_handler(function($severity, $message) {
if ($severity === E_WARNING) {
error_log("[WARNING] {$message}");
// 这里可以发 Slack、写 DB、或 throw new RuntimeException($message)
}
});
<p>// 下面这行会触发 handler
$foo = $undefined_var . 'test';</p><p>// 但下面这行不会:@ 操作符阻止了 handler 执行
@$bar = $undefined_var2 . 'test';
</p>
AI SDK 的 warning 往往藏在底层 HTTP 调用或 JSON 解析里,想稳定捕获就得去掉抑制、接管底层 I/O,或者直接切换到异常驱动的 SDK 封装——否则只是在捕获“运气好没被屏蔽”的 warning。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











