問題
有一個轉賬介面,呼叫到支付寶的單筆轉賬介面,大部分時間能成功,偶爾會出現失敗,列印支付寶介面返回,只有返回false,沒有其他資訊了。問支付寶的客服,回覆說沒有查到失敗訂單的記錄。 被這個問題困擾了好久,直到有一天去檢視支付寶sdk底層的程式碼,發現有個地方的錯誤是沒有記錄到,直接返回false的。
- 最終向外發起請求的程式碼
try {
$resp = $this->curl($requestUrl, $apiParams);
} catch (Exception $e) {
$this->logCommunicationError($sysParams["method"], $requestUrl, "HTTP_ERROR_" . $e->getCode(), $e->getMessage());
return false; # 前面處理了錯誤後,這裡僅返回false
}
- 裡面的logCommunicationError方法:
protected function logCommunicationError($apiName, $requestUrl, $errorCode, $responseTxt)
{
$logData = array(
date("Y-m-d H:i:s"),
$apiName,
$this->appId,
PHP_OS,
$this->alipaySdkVersion,
$requestUrl,
$errorCode,
str_replace("\n", "", $responseTxt)
);
echo json_encode($logData); # 這裡直接echo出去,我們生產環境中無法拿到這個資訊
}
於是,將這個$logData寫到日誌檔案裡面,最終記錄到錯誤:
"HTTP_ERROR_0","HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)"
解決
修改curl方法,新增以下行:
protected function curl($url, $postFields = null)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
# 強制使用http1.1
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); # 新增
curl_setopt($ch, CURLOPT_FAILONERROR, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
.
.
.
問題解決
參考
本作品採用《CC 協議》,轉載必須註明作者和本文連結