Closed rpmgr closed 3 years ago
Hi @rpmgr,
I tried to reproduce this issue without success so far. Could you provide the following information?
Your environment:
_You can paste the output generated by our complementary script: https://github.com/googleads/google-ads-php/blob/master/scripts/print_php_information.php._
Alternatively, please provide with the following pieces of information:
php -v
.php -r 'print php_uname();'
._protobuf
is used or not: Run php -r 'print phpversion("protobuf");'
.grpc
is used or not: Run php -r 'print phpversion("grpc");'
.grpc
or rest
): See https://developers.google.com/google-ads/api/docs/client-libs/php/transport.Steps to reproduce:
You can paste the piece of code that fails here.
Environment:
================= PHP GENERAL INFORMATIONFYI: PHP Version and gRPC version in my dev is 7.4.21 and 1.38.0 respectively. OS in dev is Ubuntu 18.04.3 LTS and Debian 4.19.194-3 in production.
================================= Steps to reproduce: While trying to upload conversion I get the error.
Piece of code that fails:
namespace GPBMetadata\Google\Ads\GoogleAds\V8\Services;
class ConversionUploadService
{
public static $is_initialized = false;
public static function initOnce() {
$pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool();
if (static::$is_initialized == true) {
return;
}
\GPBMetadata\Google\Api\Http::initOnce();
\GPBMetadata\Google\Api\Annotations::initOnce();
\GPBMetadata\Google\Api\FieldBehavior::initOnce();
\GPBMetadata\Google\Api\Resource::initOnce();
\GPBMetadata\Google\Api\Client::initOnce();
\GPBMetadata\Google\Protobuf\Any::initOnce();
\GPBMetadata\Google\Rpc\Status::initOnce();
$pool->internalAddGeneratedFile(
'
�
@google/ads/googleads/v8/services/conversion_upload_service.proto google.ads.googleads.v8.servicesgoogle/api/client.protogoogle/api/field_behavior.protogoogle/api/resource.protogoogle/rpc/status.proto"� UploadClickConversionsRequest customer_id ( B�AK conversions (21.google.ads.googleads.v8.services.ClickConversionB�A partial_failure (B�A
validate_only ("� UploadClickConversionsResponse1 partial_failure_error (2.google.rpc.StatusH results (27.google.ads.googleads.v8.services.ClickConversionResult"� UploadCallConversionsRequest customer_id ( B�AJ conversions (20.google.ads.googleads.v8.services.CallConversionB�A partial_failure (B�A
validate_only ("� UploadCallConversionsResponse1 partial_failure_error (2.google.rpc.StatusG results (26.google.ads.googleads.v8.services.CallConversionResult"� ClickConversion gclid ( H � conversion_action ( H�! conversion_date_time ( H� conversion_value (H�
currency_code ( H� order_id ( H�\\ external_attribution_data (29.google.ads.googleads.v8.services.ExternalAttributionDataJ custom_variables (20.google.ads.googleads.v8.services.CustomVariable= cart_data (2*.google.ads.googleads.v8.services.CartDataB _gclidB _conversion_actionB _conversion_date_timeB _conversion_valueB _currency_codeB _order_id"� CallConversion caller_id ( H �! call_start_date_time ( H� conversion_action ( H�! conversion_date_time ( H� conversion_value (H�
currency_code ( H�J custom_variables (20.google.ads.googleads.v8.services.CustomVariableB
_caller_idB _call_start_date_timeB _conversion_actionB _conversion_date_timeB _conversion_valueB _currency_code"� ExternalAttributionData( external_attribution_credit (H �\' external_attribution_model ( H�B _external_attribution_creditB _external_attribution_model"� ClickConversionResult gclid ( H � conversion_action ( H�! conversion_date_time ( H�B _gclidB _conversion_actionB _conversion_date_time"� CallConversionResult caller_id ( H �! call_start_date_time ( H� conversion_action ( H�! conversion_date_time ( H�B
_caller_idB _call_start_date_timeB _conversion_actionB _conversion_date_time"{ CustomVariableZ conversion_custom_variable ( B6�A3 1googleads.googleapis.com/ConversionCustomVariable value ( "� CartData merchant_id ( feed_country_code ( feed_language_code ( local_transaction_cost (> items (2/.google.ads.googleads.v8.services.CartData.Item@ Item
product_id ( quantity (
unit_price (2� ConversionUploadService� UploadClickConversions?.google.ads.googleads.v8.services.UploadClickConversionsRequest@.google.ads.googleads.v8.services.UploadClickConversionsResponse"i���9"4/v8/customers/{customer_id=*}:uploadClickConversions:*�A\'customer_id,conversions,partial_failure� UploadCallConversions>.google.ads.googleads.v8.services.UploadCallConversionsRequest?.google.ads.googleads.v8.services.UploadCallConversionsResponse"h���8"3/v8/customers/{customer_id=*}:uploadCallConversions:*�A\'customer_id,conversions,partial_failureE�Agoogleads.googleapis.com�A\'https://www.googleapis.com/auth/adwordsB� $com.google.ads.googleads.v8.servicesBConversionUploadServiceProtoPZHgoogle.golang.org/genproto/googleapis/ads/googleads/v8/services;services�GAA� Google.Ads.GoogleAds.V8.Services� Google\\Ads\\GoogleAds\\V8\\Services�$Google::Ads::GoogleAds::V8::Servicesbproto3'
, true);
static::$is_initialized = true;
}
Hi @PierrickVoulet,
Some background:
I've installed C implementation of grpc and protobuf using PECL. I've installed the client library using composer install
and I think, it might have installed the PHP version of grpc and protobuf as well to use with rest
?
To reproduce the error:
rest
in the code using following line:
->withTransport('rest')
I get the following error:
#0 /home/vagrant/google-oct/app/Vendor/google/gax/src/Transport/RestTransport.php(125): Google\Protobuf\Internal\Message->mergeFromJsonString()
#1 /home/vagrant/google-oct/app/Vendor/guzzlehttp/promises/src/Promise.php(204): Google\ApiCore\Transport\RestTransport->Google\ApiCore\Transport\{closure}()
#2 /home/vagrant/google-oct/app/Vendor/guzzlehttp/promises/src/Promise.php(153): GuzzleHttp\Promise\Promise::callHandler()
#3 /home/vagrant/google-oct/app/Vendor/guzzlehttp/promises/src/TaskQueue.php(48): GuzzleHttp\Promise\Promise::GuzzleHttp\Promise\{closure}()
#4 /home/vagrant/google-oct/app/Vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(118): GuzzleHttp\Promise\TaskQueue->run()
#5 /home/vagrant/google-oct/app/Vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php(145): GuzzleHttp\Handler\CurlMultiHandler->tick()
#6 /home/vagrant/google-oct/app/Vendor/guzzlehttp/promises/src/Promise.php(248): GuzzleHttp\Handler\CurlMultiHandler->execute()
#7 /home/vagrant/google-oct/app/Vendor/guzzlehttp/promises/src/Promise.php(224): GuzzleHttp\Promise\Promise->invokeWaitFn()
#8 /home/vagrant/google-oct/app/Vendor/guzzlehttp/promises/src/Promise.php(269): GuzzleHttp\Promise\Promise->waitIfPending()
#9 /home/vagrant/google-oct/app/Vendor/guzzlehttp/promises/src/Promise.php(226): GuzzleHttp\Promise\Promise->invokeWaitList()
#10 /home/vagrant/google-oct/app/Vendor/guzzlehttp/promises/src/Promise.php(62): GuzzleHttp\Promise\Promise->waitIfPending()
#11 /home/vagrant/google-oct/app/Vendor/googleads/google-ads-php/src/Google/Ads/GoogleAds/V8/Services/Gapic/ConversionUploadServiceGapicClient.php(302): GuzzleHttp\Promise\Promise->wait()
#12 /home/vagrant/google-oct/app/Controller/Component/GoogleAdsApiComponent.php(383): Google\Ads\GoogleAds\V8\Services\Gapic\ConversionUploadServiceGapicClient->uploadClickConversions()
#13 /home/vagrant/google-oct/app/Controller/Component/GoogleAdsApiComponent.php(129): GoogleAdsApiComponent->uploadOfflineConversion()
#14 /home/vagrant/google-oct/app/Controller/ServicesController.php(8544): GoogleAdsApiComponent->handleOfflineConversion()
#15 [internal function]: ServicesController->testGoogleAdsLib()
#16 /home/vagrant/google-oct/lib/Cake/Controller/Controller.php(499): ReflectionMethod->invokeArgs()
#17 /home/vagrant/google-oct/lib/Cake/Routing/Dispatcher.php(193): Controller->invokeAction()
#18 /home/vagrant/google-oct/lib/Cake/Routing/Dispatcher.php(167): Dispatcher->_invoke()
#19 /home/vagrant/google-oct/app/webroot/index.php(110): Dispatcher->dispatch()
#20 {main}
Error: Error occurred during parsing: Error parsing JSON @7:87: Type was not found
Also, could it be that my git command line is changing LF
to CRLF
while pushing the file to repo. I get following warning while pushing all the libs files:
The file will have its original line endings in your working directory warning: LF will be replaced by CRLF in ...
Thanks,
@rpmgr Thank you for the additional information, this is helpful!
If you have installed the C implementation of grpc and protobuf using PECL then you can use the grpc
transport, no need to set it up to rest
.
Could you provide us with the actual code that you execute and that fails, and the error logs when it fails using grpc
as a transport? I tried to change the end of line to CRLF on my side but, as far as I can tell, it does not make it fail on my end.
Hi @PierrickVoulet, thank you for your quick response.
The codes are separated into different class files as a method. I'll paste the methods involved below:
public function testGoogleAdsLib()
{
echo 'Test Upload Conversion';
$this->getComponent('GoogleAdsApi');
$data = [ 'id' => 1, 'related_id' => 18948, 'related_table' => 'policies', 'product_type' => 'warranty', 'gclid' => 'test1', 'conversion_action_id' => 758401197, 'created' => '2021-08-26 18:50:21', ];
try {
$response = $this->GoogleAdsApi->handleOfflineConversion($data);
echo 'Response status: ' . $response;
} catch (Exception $e) {
echo '<pre>';
print_r($e->getTraceAsString());
echo '</pre>';
echo 'Error: ' . $e->getMessage();
}
if ($this->GoogleAdsApi->hasError()) {
echo '<pre>';
print_r($this->GoogleAdsApi->getErrors());
echo '</pre>';
}
exit();
}
/*================================================================================*/
public function handleOfflineConversion(array $data = []): bool
{
if(empty($data)) {
return false;
}
$this->resetError();
$errors = [];
try {
$this->uploadOfflineConversion(
$this->googleAdsClient,
$this->getCustomerId($data['product_type']),
$data['conversion_action_id'],
$data['gclid'],
$this->getConversionDateTime($data['created'])
);
} catch (GoogleAdsException $googleAdsException) {
$errors[] = sprintf(
"Request with ID '%s' has failed.%sGoogle Ads failure details:%s",
$googleAdsException->getRequestId(),
PHP_EOL,
PHP_EOL
);
foreach ($googleAdsException->getGoogleAdsFailure()->getErrors() as $error) {
/** @var GoogleAdsError $error */
$errors[] = sprintf(
"\t%s: %s%s",
$error->getErrorCode()->getErrorCode(),
$error->getMessage(),
PHP_EOL
);
}
$this->addErrors($errors);
} catch (ApiException $apiException) {
$errors[] = sprintf(
"ApiException was thrown with message '%s'.%s",
$apiException->getMessage(),
PHP_EOL
);
$this->addErrors($errors);
}
if ($this->hasError()) {
$this->addLog(
[
'action' => 'upload',
'data' => $data,
],
$data['related_table'],
$data['related_id']
);
return false;
}
return true;
}
/*================================================================================*/
private function uploadOfflineConversion(
GoogleAdsClient $googleAdsClient,
int $customerId,
int $conversionActionId,
string $gclid,
string $conversionDateTime,
string $conversionCustomVariableId = null,
string $conversionCustomVariableValue = null
): void {
// Creates a click conversion by specifying currency as GBP.
$clickConversion = new ClickConversion([
'conversion_action' => ResourceNames::forConversionAction($customerId, $conversionActionId),
'gclid' => $gclid,
'conversion_value' => self::CONVERSION_VALUE,
'conversion_date_time' => $conversionDateTime,
'currency_code' => self::CURRENCY_CODE
]);
if (!is_null($conversionCustomVariableId) && !is_null($conversionCustomVariableValue)) {
$clickConversion->setCustomVariables([
new CustomVariable([
'conversion_custom_variable' => ResourceNames::forConversionCustomVariable(
$customerId,
$conversionCustomVariableId
),
'value' => $conversionCustomVariableValue
])
]);
}
// Issues a request to upload the click conversion.
$conversionUploadServiceClient = $googleAdsClient->getConversionUploadServiceClient();
$response = $conversionUploadServiceClient->uploadClickConversions(
$customerId,
[$clickConversion],
true
);
if (!is_null($response->getPartialFailureError())) {
$this->addError(
sprintf(
"Partial failures occurred: '%s'.%s",
$response->getPartialFailureError()->getMessage(),
PHP_EOL
)
);
}
}`
I don't have the server access so, I would have to print the grpc
error log when I run the test through browser. Is there any information as how I can do that or you could point me to right direction?
Thanks,
Thank you @PierrickVoulet for taking time to look into this.
I've fixed this now and this issue can be closed. It seems to be the problem with the repo, during deployment it somehow might have corrupted binary files.
However, when C implementation of grpc
is enabled in php.ini and rest
transport is enabled from code ->withTransport('rest')
it still gives the above error.
I'm not sure if that's the intended behaviour.
Thanks,
I am glad you found the issue and thank you for sharing the resolution.
I was able to reproduce the issue related to REST on my end as well, I created a new issue for it https://github.com/googleads/google-ads-php/issues/641.
Hi,
My code is working fine on Dev server but throws Error on Production server, am I missing anything on Production?
Error: Fatal Error (1): Failed to parse binary descriptor in [../app/Vendor/googleads/google-ads-php/metadata/Google/Ads/GoogleAds/V8/Services/ConversionUploadService.php, line 124]
Thanks in advance.