Google PHP API:"来自api服务器的无效响应"

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.php312

该文件确实是在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位于应用程序代码本身的某个位置。我的猜测是,应用程序代码中有一种与上面类似的捕获所有异常处理块,它会吞掉任何类型的非成功响应,并以不透明的错误消息作为致命错误来解决。

我能给出的最好答案是在代码中查找错误消息的来源,然后告诉它记录详细信息而不是掩盖它们,这可能会揭示潜在的问题是什么以及如何修复它。