5

Yerel PHP'de Google App Engine'de çalıştırdığım bir uygulamada Google PHP API İstemcisi v2.0'ı kullanıyorum. Uygulamamı Google App Engine üretimine yayınladığımda, hatayı almadım, ancak aralıklı olduğu için üretimde şanslı olup olmadığımı bilmek zor.Google PHP API: "api sunucusundan geçersiz yanıt"

Google API istemcim Google Drive'a bir dosya yazmaya çalışıyor. Bu kod birkaç aydır iyi çalışıyor, ama bu sabah aniden çalışmayı bıraktı. Google API durumunu kontrol ettim ve herhangi bir kesinti bildirmiyorlar.

Önemli hata: fopen(): API sunucusundan geçersiz bir yanıt API çağrıları herhangi yürütmek, ben bu muğlak hata yanıtını olsun. on line /Users/me/googleappengine/stuff-otherstuff-111111/vendor/guzzlehttp/guzzle/src/Handler/StreamHandler.php yılında

dosyayı Google'da oluşturulan olsun demek Drive, bu yüzden API çağrım geçiyor, ancak betiğime geri dönüş her ne olursa olsun ölümcül bir kazaya neden oluyor.

Birkaç dakika için tekrar çalışmaya başladı, şimdi tekrar çöküyor. Invalid response from API server numaralı hataya herhangi bir çözüm bulamadım ... ve aralıklı. Kodumla ilgili bir şey görünmüyor, ancak Google herhangi bir kesinti olmadığını söylüyor.

Neyi eksik? Bunu nasıl düzeltebilirim?

<?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"; 
} 

DÜZENLEME: Kodum Invalid response from API server mesajla şimdi sürekli başarısız gibi görünüyor. Sadece kodun Google ile iletişim kurduğu bir noktada başarısız olur. Bu iki yer, refreshToken() (yalnızca nadiren gerçekleşir) ve diğeri ise create()'u aradığımda.

Arkadaşımın aynı kodu (aynı kod, aynı libs, aynı oauth jetonu, vb.) Söyleyebildiğimiz kadarıyla makinede bu kodu çalıştırdım ve onun için çalışıyor.

Notlar: getSetting() yukarıdaki kod işlevini, yalnızca veritabanları veritabanımdan yapılandırma amacıyla kullandığım bazı dizelerden alır. Ayrıca, setHttpClient() numaralı çağrıya ihtiyaç duyulur çünkü bu, Google Drive Engine'in içinde çalışan ve çalışan bir CA Bundle'a sahip olan PHP 5.5'te çalışan ve bana uygun bir tane sunmamı gerektiren Google App Engine'in içinde çalışıyor.

Her seferinde benim için başarısız olmasına neden olabilir ama arkadaşım için çalışabilir?

+0

bir hata neden olan kodu sonrası gerekecektir. – DaImTo

+0

Belirli bir kod parçası değil. Aralıklı olarak gerçekleşir ve Google'a bir api araması yapan herhangi bir kod satırında gerçekleşebilir. Bir kez, bir Uzaktan Apps Komut Dosyası çağrısı yürüten satırda bir hata oluştuğunda, bir dosya listesi almak için bir Google Drive araması yaptığımda başka bir kez gerçekleşir. dosya. Ama daha sonra aynı çağrıların hepsi önümüzdeki 20 kez kod çalıştıracağım. –

+0

Sorunda hataya neden olan şey hakkında yeterli bilgi yok. [Https://github.com/google/google-api-php-client] kullandığınız PHP API istemcisidir. "StreamHandler" kodundaki "fopen" hatasına dayanarak, hatanın Drive'dan bir dosya oluşturup okumasıyla gerçekleştiğinden şüpheleniyorum. Lütfen bu hatayı yeniden oluşturabilecek minimum bir kod örneği sağlayın ve buna bakmaktan mutlu oluruz. – Nicholas

cevap

-1

"Bu hataya neden olanı" yanıtlayabilmeniz için önce "hatanın ne" olduğunu yanıtlamanız gerekir. Genellikle, geçici ağ hataları normaldir ve sürekli olarak gerçekleşse bile (örneğin, bir kesinti durumunda veya sizin durumunuzda, bazı yerel sorunlarda) uygulamayı ölümcül bir hatayla çarpışmaya zorlamaz.

Guzzle, hataları kesinlikle ölümcül davranmıyor, çünkü sets its default HTTP context to ignore_errors => true (ve yine de yanıtı döndürür). google-api-php-client, ignore_errors'un varsayılan davranışını, ne de google-api-php-client-services'u veya geliştirme sunucusunu veya PHP SDK'sini değiştirmez. Invalid response from API server metni, söz konusu projelerden herhangi birinin kaynak kodunda herhangi bir yerde görünmez ve API'lardan herhangi birinden belgelenmiş bir hata yanıtı değildir.

Yani Invalid response from API server kaynak uygulama kodu kendi içinde bir yerlerde olduğunu öneririm, göz önüne alındığında. Benim tahminim, uygulama kodunda, herhangi bir başarılı olmayan yanıtı yutan ve ölümcül bir hata mesajı ile kurtarmaya çalıştığınız benzer bir yakalama istisnası taşıma bloğu olmasıdır.

Verebileceğim en iyi cevap, kodunuzdaki hata iletisinin kaynağını aramaktır, ardından ayrıntıları gizlemek yerine ayrıntıları günlüğe kaydetmesini söyler; bu, temel sorunun ne olduğunu ve nasıl düzeltileceğini gösterir.

+0

sizin' catch içine 'deneyebilirsiniz Gerçekten bu kadar yararlı değil. –

+0

Hayır, cevabım, bir bulut API'sinden ara sıra 200 olmayan bir cevabın normal olması ve incelikle ele alınması gerektiğidir. Bu, posterin bildirdiği gibi, söz konusu hata nedeniyle uygulamanın çökmesine neden olan büyük bir olaydır, ancak API ya da istemci kütüphanesi ya da uygulamayı çökmeye zorlayan SDK değildir, bu yüzden mantıksal sonuç: Uygulama koduna bakın. – Adam

+0

Ama arada bir sorunu açıklayan değil, o herhangi bir üretim uygulaması için tam bir showstopper olacağını böyle yüksek frekansta oluyor bir sorun tanımladığı. Uygulama kodu yukarıda yer almaktadır ve zamanın tamamı, yarısı veya hatta üçte biri başarısız olmamalıdır. Bu başarısızlık oranı gülünç. –