5

我在本地主機上的Google App Engine上運行的應用程序中使用Google PHP API Client v2.0。當我將應用程序發佈到Google App Engine製作時,我沒有收到錯誤,但是它是間歇性的,所以很難知道我是否在生產中幸運。Google PHP API:「來自api服務器的無效響應」

我的Google API客戶端正在嘗試將文件寫入我的Google雲端硬盤。這段代碼已經運行了好幾個月,但今天早上它突然停止了工作。我檢查了Google API的狀態,他們沒有報告任何中斷。當我執行任何的API調用,我得到這個模糊的錯誤響應:

致命錯誤:fopen()函數:從API服務器的響應無效。在 /Users/me/googleappengine/stuff-otherstuff-111111/vendor/guzzlehttp/guzzle/src/Handler/StreamHandler.php 上線

該文件確會在谷歌創建驅動器,所以我的API調用正在通過,但無論什麼反饋回到我的腳本導致一個致命的崩潰。

幾分鐘後它又開始工作了,現在又崩潰了。我無法在任何地方真的找到任何解決方案到錯誤Invalid response from API server ......並且它是間歇性的。它似乎不是我的代碼,但Google說它沒有任何中斷。

我錯過了什麼?我怎樣才能解決這個問題?

<?php 
include_once('code-base.php'); 
require_once('vendor/autoload.php'); 

$client = new Google_Client(); 
$client->setApplicationName(getSetting('APP_NAME')); 
$client->setAuthConfig(json_decode(getSetting('localhost_google_client_secret'), true)); 
$client->setAccessType("offline"); 
$client->setScopes(array(Google_Service_Drive::DRIVE)); 

$client->setHttpClient(new GuzzleHttp\Client(['verify'=>'ca-bundle.crt'])); 

$accesstoken = json_decode(getSetting('localhost_google_oauth_token'), true); 

$client->setAccessToken($accesstoken); 

// Refresh the token if it's expired. 
if ($client->isAccessTokenExpired()) { 
    print "access token is expired\n"; 

    $refreshtoken = getSetting('localhost_google_refresh_token'); 

    print "refresh token: $refreshtoken\n"; 

    $client->refreshToken($refreshtoken); 
    $newtokenjson = json_encode($client->getAccessToken()); 

    print "new token: $newtokenjson\n"; 

    printf("before: %s\n\nafter: %s\n\n", $accessToken, $newtokenjson); 
    //file_put_contents($credentialsPath, $newtokenjson); 
    updateSetting('localhost_google_oauth_token', $newtokenjson); 
} 

print "after checking access token expired\n"; 

print "before drive service\n"; 
$driveservice = new Google_Service_Drive($client); 
print "after drive service\n"; 

$parentfolderid = getSetting('GDRIVE_EXPORT_DUMP'); 
$title = "00005 test gdrive.csv"; 
$filetype = 'text/csv'; 
$contents = "The quick brown fox jumped over the lazy dog."; 

$file = new Google_Service_Drive_DriveFile(); 
$file->setName($title); 
$file->setDescription($title); 
$file->setMimeType($filetype); 

$file->setParents(array($parentfolderid)); 

try { 

    if ($contents == null) { 
     print "contents of file are null, creating empty file\n"; 
     $createdFile = $driveservice->files->create($file); 
     print "after creating empty file\n"; 

    } else { 
     $contentsarray = array('data' => $contents, 'mimeType' => $filetype, 'uploadType' => 'media'); 
     if ($options != null) { 
      foreach($options as $key => $value) { 
       $contentsarray[$key] = $value; 
      } 
     } 
     print "file contents: ".var_export($contentsarray, true)."\n"; 
     $createdFile = $driveservice->files->create($file, $contentsarray); 
     print "after create file with contents\n"; 
    } 

    return $createdFile; 
} catch (Exception $e) { 
    print "EXCEPTION: An error occurred: " . $e->getMessage()."\n"; 
} 

編輯:我的代碼似乎是一貫現在用Invalid response from API server消息失敗。它只會在代碼與Google溝通的地方失敗。這兩個地方是當我打電話refreshToken()(這隻發生很少),另一個是當我打電話create()

我有我的朋友。他的機器上運行這個確切的代碼相同的設置(據我們所知......相同的代碼,相同的庫,同樣的OAuth令牌等),併爲他工作。

注:getSetting()功能上面的代碼只是拉從我的數據庫一些字符串,我使用的配置的目的。此外,還需要調用setHttpClient(),因爲這是在運行PHP 5.5的Google App Engine中運行的,該程序包含CA Bundle,它要求我提供一個適當的CA Bundle。

什麼引起它爲我的朋友每一次,但工作不能給我嗎?

+0

您將需要發佈導致錯誤的代碼。 – DaImTo

+0

這不是任何特定的代碼。它會間歇性地發生,並且可能發生在任何使API調用Google的代碼行上。有一次執行遠程應用程序腳本調用的線路發生錯誤,另一次發生在我進行Google Drive調用以獲取文件列表時,另一次發生在Google Drive調用中以創建一個文件文件。但接下來所有這些相同的調用將在未來20次運行代碼時發揮作用。 –

+0

關於問題中導致錯誤的原因信息不足。我假設[this](https://github.com/google/google-api-php-client)是您正在使用的PHP API客戶端。根據'StreamHandler'代碼中的'fopen'錯誤,我懷疑從Drive創建或讀取文件時發生錯誤。請提供可重現此錯誤的最小代碼示例,我們很樂意查看它。 – Nicholas

回答

-1

之前,你可以回答「是什麼原因造成這個錯誤」你首先需要回答「什麼是錯誤」。通常情況下,瞬時網絡錯誤是正常的,即使它們經常發生(例如發生中斷或遇到本地問題),也不會強制應用程序發生致命錯誤。

狂飲肯定不會把錯誤,致命的,因爲它sets its default HTTP context to ignore_errors => true(反正返回響應)。 google-api-php-client不會更改ignore_errors的默認行爲,也不會更改google-api-php-client-services,也不會更改開發服務器和PHP SDK的默認行爲。文本Invalid response from API server沒有出現在任何上述項目的源代碼中,也沒有來自任何API的記錄錯誤響應。

因此,它會暗示Invalid response from API server的來源是在應用程序代碼本身的某個地方。我的猜測是,在應用程序代碼中存在一個類似於catch-all的異常處理塊,因爲上面有吞嚥任何類型的非成功響應,並且以不透明的錯誤消息作爲致命消息。

我可以給出的最佳答案是在代碼中尋找錯誤消息的來源,然後告訴它記錄細節而不是模糊它們,這可能揭示底層問題是什麼以及如何解決它。

+0

這個答案看起來很像「這不應該發生......如果它確實沒有什麼大不了的。」沒有那麼有用。 –

+0

不,我的答案是偶爾來自雲API的非200響應是正常的,應該優雅地處理。正如海報報道的那樣,由於上述錯誤,應用程序會崩潰,但這不是API,也不是客戶端庫,也不是強制應用程序崩潰的SDK,所以合乎邏輯的結論是看看應用程序代碼本身。 – Adam

+0

但他沒有描述偶然的問題,他描述的問題發生頻率如此之高,以至於它將成爲任何生產應用的完美展現者。應用程序代碼包含在上面,它不應該全部,一半,甚至三分之一的時間都失敗。這個失敗率是可笑的。 –