支付寶轉賬介面HTTP/2 stream 0 was not closed close cleanly報錯解決

tsin發表於2021-12-12

問題

有一個轉賬介面,呼叫到支付寶的單筆轉賬介面,大部分時間能成功,偶爾會出現失敗,列印支付寶介面返回,只有返回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 協議》,轉載必須註明作者和本文連結
Was mich nicht umbringt, macht mich stärker

相關文章