Rya*_*lla 5 php google-app-engine google-api google-drive-api google-api-php-client
我在我在localhost上的Google App Engine上运行的应用中使用Google PHP API Client v2.0.当我将我的应用程序发布到Google App Engine生产时,我没有得到错误,但它是间歇性的,因此很难知道我是否只是在生产中变得幸运.
我的Google API客户端正在尝试将文件写入我的Google云端硬盘.这段代码已经运行了好几个月,但它今天早上突然停止工作.我检查了Google API状态,但他们没有报告任何中断.当我执行任何API调用时,我得到这个模糊的错误响应:
致命错误:fopen():来自API服务器的响应无效.在 /Users/me/googleappengine/stuff-otherstuff-111111/vendor/guzzlehttp/guzzle/src/Handler/StreamHandler.php 第312行
该文件确实是在Google云端硬盘上创建的,因此我的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";
}
Run Code Online (Sandbox Code Playgroud)
编辑:我的代码现在似乎与Invalid response from API server消息一致失败.它只会在代码与Google通信时失败.这两个地方是我打电话的时候refreshToken()(很少发生),另一个是我打电话的时候create().
我让我的朋友在他的机器上使用相同的设置运行这个确切的代码(据我们所知...相同的代码,相同的库,相同的oauth令牌等)并且它适用于他.
注意:getSetting()上面的代码只是从我的数据库中提取一些字符串,用于配置目的.此外,setHttpClient()需要进行调用,因为这是在运行在PHP 5.5上的Google App Engine中运行的,该应用程序有一个搞砸的CA Bundle,它需要我提供一个正确的.
什么可能导致它每次失败,但为我的朋友工作?
Ada*_*dam -1
在回答“导致此错误的原因”之前,您首先需要回答“错误是什么”。通常,暂时性网络错误是正常的,不会迫使应用程序因致命错误而崩溃,即使它们不断发生(例如,在发生中断或在您的情况下,出现一些本地问题)。
Guzzle 当然不会将错误视为致命错误,因为它将默认 HTTP 上下文设置为ignore_errors => true(并返回响应)。不会更改、 、 、、 开发服务器或 PHP SDKgoogle-api-php-client的默认行为。该文本不会出现在上述任何项目的源代码中的任何位置,也不是任何 API 的记录错误响应。ignore_errorsgoogle-api-php-client-servicesInvalid response from API server
因此,这表明 的来源Invalid response from API server位于应用程序代码本身的某个位置。我的猜测是,应用程序代码中有一种与上面类似的捕获所有异常处理块,它会吞掉任何类型的非成功响应,并以不透明的错误消息作为致命错误来解决。
我能给出的最好答案是在代码中查找错误消息的来源,然后告诉它记录详细信息而不是掩盖它们,这可能会揭示潜在的问题是什么以及如何修复它。
| 归档时间: |
|
| 查看次数: |
751 次 |
| 最近记录: |