5

localhost의 Google App Engine에서 실행중인 앱에서 Google PHP API 클라이언트 v2.0을 사용하고 있습니다. 내 앱을 Google App Engine 프로덕션에 게시 할 때 오류가 발생하지 않았지만 간헐적으로 인해 프로덕션 환경에서 운이 좋았는지 알기가 어렵습니다.Google PHP API : "api 서버의 응답이 없습니다."

내 Google API 클라이언트가 내 Google 드라이브에 파일을 쓰려고합니다. 이 코드는 2 개월 동안 잘 작동했지만 오늘 아침에 갑자기 작동을 멈췄습니다. Google API 상태를 확인했는데 중단이보고되지 않습니다.

치명적인 오류 :하면 fopen() API 서버에서 잘못된 응답 내가 API 호출 중 하나를 실행하면,이 모호한 오류 응답을 얻을. 라인 /Users/me/googleappengine/stuff-otherstuff-111111/vendor/guzzlehttp/guzzle/src/Handler/StreamHandler.php312

파일은 구글에 생성됩니까 드라이브 때문에 내 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() 호출이 필요합니다. 이는 CA 묶음이 엉망인 PHP 5.5에서 실행되는 Google App Engine 내부에서 실행되기 때문에 호출해야하며 적절한 패키지를 제공해야합니다.

매번 나를 위해 실패 할 수도 있지만 내 친구를 위해 일할 수 있습니까?

+0

오류의 원인이되는 코드를 게시해야합니다. – DaImTo

+0

특정 코드는 아닙니다. 간헐적으로 발생하며 Google에 API 호출을하는 모든 코드 행에서 발생할 수 있습니다. Remote Apps Scripts 호출을 실행하는 행에서 오류가 발생하는 경우, Google 드라이브 호출을 통해 파일 목록을 가져올 때마다 또 다른 시점에 Google 드라이브 호출을 통해 파일 목록을 가져올 때 파일. 그런 다음 동일한 호출이 모두 코드를 실행하는 다음 20 번 작동합니다. –

+0

질문에서 오류의 원인에 대한 정보가 충분하지 않습니다. [this] (https://github.com/google/google-api-php-client)가 사용중인 PHP API 클라이언트라고 가정합니다. 'StreamHandler' 코드에서'fopen' 오류를 기반으로, 나는 드라이브에서 파일을 생성하거나 읽는 중 오류가 발생했다고 의심합니다. 이 오류를 재현 할 수있는 최소한의 코드 샘플을 제공해 주시면 기꺼이 조사해 드리겠습니다. – Nicholas

답변

-1

"이 오류의 원인"에 대답하기 전에 먼저 "무엇이 오류입니까?"라고 대답해야합니다. 일반적으로 일시적인 네트워크 오류는 정상적으로 발생하며 앱이 계속해서 (예 : 정전 또는 사용자의 경우 현지 문제가 발생한 경우) 치명적인 오류로 앱이 강제로 중단되지 않습니다.

Guzzle은 오류를 치명적인 것으로 취급하지 않습니다. 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

그러나 그는 가끔 문제를 설명하지 않고 있으며, 높은 빈도로 발생하는 문제를 기술하고있어 모든 제작 응용 프로그램에 대한 완벽한 쇼가 될 것입니다. 응용 프로그램 코드는 위에 포함되어 있으며 모든 시간, 절반 또는 심지어 3 분의 1은 실패하지 않아야합니다. 그 실패율은 우스꽝 스럽다. –