post-install-cmd中try/catch无效,因composer install失败时直接以非零退出码终止进程,根本不执行PHP脚本;错误捕获必须在shell层通过$?和stderr实现。

post-install-cmd 里 try/catch 为什么完全没用
因为 composer install 在依赖解析失败、网络超时或权限错误时,压根不会进入 PHP 脚本执行阶段——它直接以非零退出码终止进程,post-install-cmd 根本不会被调用。你在 scripts 里写的任何 PHP 逻辑(包括 try/catch)都形同虚设。
真正能拦截错误的位置只有 shell 层
必须把 composer install 包裹在外部 shell 脚本中,靠捕获其 $?(退出码)和 stderr 输出来判断成败:
- 退出码非 0 → 安装失败,此时可触发上报、发告警、存日志
-
stderr中含Could not fetch、403 Forbidden、failed to clone等关键词,可分类归因 - 不要依赖
pre-install-cmd记录时间戳就以为能“兜底”,它不保证后续命令真能执行到
--no-scripts 是绕过脚本干扰的前提
如果你的 post-install-cmd 本身会出错(比如调用了不存在的 phpunit),反而会掩盖主安装失败的真实原因。建议在自动化流程中统一加 --no-scripts,让 wrapper 脚本成为唯一错误出口:
composer install --no-scripts --no-dev --optimize-autoloader- 再用
if [ $? -ne 0 ]; then echo "install failed" >&2; exit 1; fi显式中断 - 避免把错误处理逻辑分散到多个钩子里,容易漏判或重复上报
CI/CD 中最容易忽略的点:GitHub Token 权限与 auth.json 权限
很多看似“安装失败”的场景,其实是 composer update 卡在 api.github.com 上静默降级为匿名请求,然后因速率限制返回 403 —— 此时退出码是 0,但实际没拉到元数据。这类错误不会触发你的 shell wrapper 判断,因为命令“成功”退出了。
- 验证 GitHub Token 是否生效:
composer config --global --list | grep github-oauth,输出应为"github.com": "ghp_..." -
~/.composer/auth.json必须是600权限(Linux/macOS),否则 Composer 直接忽略该文件 - Token 至少要勾选
repo和read:packages,复制时带空格或换行会导致失效


















