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

但他没有描述偶然的问题,他描述的问题发生频率如此之高,以至于它将成为任何生产应用的完美展现者。应用程序代码包含在上面,它不应该全部,一半,甚至三分之一的时间都失败。这个失败率是可笑的。 –