기본 콘텐츠로 건너뛰기
의견 보내기
부분 실패
컬렉션을 사용해 정리하기
내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.
Google Ads API에서는 유효한 작업이 커밋되고 실패한 작업이 오류를 반환하도록 요청할 수 있습니다. 부분 실패라고 하는 이 기능을 사용하면 실패한 작업을 마지막에 별도로 처리할 수 있습니다. 이 값은 여러 Google Ads API 서비스의 get이 아닌 메서드에서 사용할 수 있습니다.
기술 세부정보
이 기능을 활용하려면 사용하려는 메서드의 partialFailure 매개변수를 설정하세요. 이는 클라이언트 라이브러리마다 약간 다를 수 있습니다. 예를 들어 MutateAdGroups을 사용하여 요청을 보낼 때 이 기능을 사용 설정하려면 다음을 실행하세요.
자바
mutateAdGroups ( String . valueOf ( customerId ), operations , true )
C#
MutateAdGroups ( customerId . ToString (), operations , true , false )
PHP
mutateAdGroups($customerId, $operations, ['partialFailure' => true])
Python
mutate_ad_groups ( customer_id , operations , partial_failure = True )
Ruby
mutate_ad_groups ( customer_id , operations , partial_failure : true )
Perl
mutate ({ customerId => $customer_id , operations => $operations , partialFailure => 'true' })
서비스는 오류가 없는 작업을 실행합니다. 성공한 작업의 결과와 실패한 작업의 오류를 반환합니다.
사용
계정에 광고 그룹을 추가해야 하는데 일부 광고 그룹에 문제가 있을 수 있다고 가정해 보겠습니다. 유효한 광고 그룹을 만들고 싶지만 오류와 함께 실패한 광고 그룹이 반환됩니다.
부분 실패를 방지해야 하는 경우
상호 종속적인 작업이 있는 요청에는 부분 실패를 사용하면 안 됩니다.
예를 들어 실적 최대화 캠페인과 같이 단일 요청에서 여러 리소스를 만들어야 하는 복잡한 항목을 만드는 경우 부분 오류를 사용하면 안 됩니다. 실적 최대화 캠페인을 처음 만들 때는 동일한 요청에서 Campaign 및 CampaignAsset 리소스를 만들어야 합니다. Campaign 생성이 실패하면 CampaignAsset 생성도 실패하므로 요청을 단일 원자적 실패로 취급해야 합니다.
또 다른 예로, AssetGroup 에 필수 애셋을 처음 추가할 때는 부분 실패를 사용하지 마세요. 애셋 그룹은 애셋 없이 또는 모든 필수 애셋을 포함하여 만들 수 있습니다. 애셋 그룹에 애셋을 처음 추가할 때는 별도의 요청에서 한 번에 하나씩 추가할 수 없습니다. 모든 항목을 하나의 요청에 포함해야 하며 부분 실패를 사용해서는 안 됩니다. 애셋 그룹에 필요한 애셋이 모두 포함된 후에는 애셋을 한 번에 하나씩 추가하거나 삭제할 수 있으며 이러한 요청은 부분 실패를 사용할 수 있습니다 .
부분 실패가 적절한지 확인하려면 동일한 요청 내에서 교차 작업 리소스 참조에 임시 ID가 필요한지 확인하세요. 이 경우 두 번째 작업의 성공 여부가 첫 번째 작업의 성공 여부에 따라 달라지므로 부분 실패를 사용하면 안 됩니다.
작업을 만들고 API 호출하기
변이 작업을 만들고 평소와 같이 API를 호출합니다.
자바
private MutateAdGroupsResponse createAdGroups (
GoogleAdsClient googleAdsClient , long customerId , long campaignId ) {
// This AdGroup should be created successfully - assuming the campaign in the params exists.
AdGroup group1 =
AdGroup . newBuilder ()
. setCampaign ( ResourceNames . campaign ( customerId , campaignId ))
. setName ( "Valid AdGroup: " + getPrintableDateTime ())
. build ();
// This AdGroup will always fail - campaign ID 0 in resource names is never valid.
AdGroup group2 =
AdGroup . newBuilder ()
. setCampaign ( ResourceNames . campaign ( customerId , 0 L ))
. setName ( "Broken AdGroup: " + getPrintableDateTime ())
. build ();
// This AdGroup will always fail - duplicate ad group names are not allowed.
AdGroup group3 =
AdGroup . newBuilder ()
. setCampaign ( ResourceNames . campaign ( customerId , campaignId ))
. setName ( group1 . getName ())
. build ();
AdGroupOperation op1 = AdGroupOperation . newBuilder (). setCreate ( group1 ). build ();
AdGroupOperation op2 = AdGroupOperation . newBuilder (). setCreate ( group2 ). build ();
AdGroupOperation op3 = AdGroupOperation . newBuilder (). setCreate ( group3 ). build ();
try ( AdGroupServiceClient service =
googleAdsClient . getLatestVersion (). createAdGroupServiceClient ()) {
// Issues the mutate request, setting partialFailure=true.
return service . mutateAdGroups (
MutateAdGroupsRequest . newBuilder ()
. setCustomerId ( String . valueOf ( customerId ))
. setCustomerId ( Long . toString ( customerId ))
. addAllOperations ( Arrays . asList ( op1 , op2 , op3 ))
. setPartialFailure ( true )
. build ());
}
}
C#
private static MutateAdGroupsResponse CreateAdGroups ( GoogleAdsClient client ,
long customerId , long campaignId )
{
// Get the AdGroupServiceClient.
AdGroupServiceClient adGroupService = client . GetService ( Services . V22 . AdGroupService );
string validAdGroupName = "Valid AdGroup: " + ExampleUtilities . GetRandomString ();
AdGroupOperation [] operations = new AdGroupOperation []
{
// This operation will be successful, assuming the campaign specified in
// campaignId parameter is correct.
new AdGroupOperation ()
{
Create = new AdGroup ()
{
Campaign = ResourceNames . Campaign ( customerId , campaignId ),
Name = validAdGroupName
}
},
// This operation will fail since we are using campaign ID = 0, which results
// in an invalid resource name.
new AdGroupOperation ()
{
Create = new AdGroup ()
{
Campaign = ResourceNames . Campaign ( customerId , 0 ),
Name = "Broken AdGroup: " + ExampleUtilities . GetRandomString ()
},
},
// This operation will fail since the ad group is using the same name as the ad
// group from the first operation. Duplicate ad group names are not allowed.
new AdGroupOperation ()
{
Create = new AdGroup ()
{
Campaign = ResourceNames . Campaign ( customerId , campaignId ),
Name = validAdGroupName
}
}
};
// Add the ad groups.
MutateAdGroupsResponse response =
adGroupService . MutateAdGroups ( new MutateAdGroupsRequest ()
{
CustomerId = customerId . ToString (),
Operations = { operations },
PartialFailure = true ,
ValidateOnly = false
});
return response ;
}
PHP
private static function createAdGroups(
GoogleAdsClient $googleAdsClient,
int $customerId,
int $campaignId
) {
$campaignResourceName = ResourceNames::forCampaign($customerId, $campaignId);
// This ad group should be created successfully - assuming the campaign in the params
// exists.
$adGroup1 = new AdGroup([
'name' => 'Valid AdGroup #' . Helper::getPrintableDatetime(),
'campaign' => $campaignResourceName
]);
// This ad group will always fail - campaign ID 0 in the resource name is never valid.
$adGroup2 = new AdGroup([
'name' => 'Broken AdGroup #' . Helper::getPrintableDatetime(),
'campaign' => ResourceNames::forCampaign($customerId, 0)
]);
// This ad group will always fail - duplicate ad group names are not allowed.
$adGroup3 = new AdGroup([
'name' => $adGroup1->getName(),
'campaign' => $campaignResourceName
]);
$operations = [];
$adGroupOperation1 = new AdGroupOperation();
$adGroupOperation1->setCreate($adGroup1);
$operations[] = $adGroupOperation1;
$adGroupOperation2 = new AdGroupOperation();
$adGroupOperation2->setCreate($adGroup2);
$operations[] = $adGroupOperation2;
$adGroupOperation3 = new AdGroupOperation();
$adGroupOperation3->setCreate($adGroup3);
$operations[] = $adGroupOperation3;
// Issues the mutate request, enabling partial failure mode.
$adGroupServiceClient = $googleAdsClient->getAdGroupServiceClient();
return $adGroupServiceClient->mutateAdGroups(
MutateAdGroupsRequest::build($customerId, $operations)->setPartialFailure(true)
);
}
Python
def create_ad_groups (
client : GoogleAdsClient , customer_id : str , campaign_id : str
) - > MutateAdGroupsResponse :
"""Creates three Ad Groups, two of which intentionally generate errors.
Args:
client: An initialized GoogleAdsClient instance.
customer_id: A valid customer account ID.
campaign_id: The ID for a campaign to create Ad Groups under.
Returns: A MutateAdGroupsResponse message instance.
"""
ad_group_service : AdGroupServiceClient = client . get_service (
"AdGroupService"
)
campaign_service : CampaignServiceClient = client . get_service (
"CampaignService"
)
resource_name : str = campaign_service . campaign_path (
customer_id , campaign_id
)
invalid_resource_name : str = campaign_service . campaign_path ( customer_id , 0 )
ad_group_operations : List [ AdGroupOperation ] = []
# This AdGroup should be created successfully - assuming the campaign in
# the params exists.
ad_group_op1 : AdGroupOperation = client . get_type ( "AdGroupOperation" )
ad_group_op1 . create . name = f "Valid AdGroup: { uuid . uuid4 () } "
ad_group_op1 . create . campaign = resource_name
ad_group_operations . append ( ad_group_op1 )
# This AdGroup will always fail - campaign ID 0 in resource names is
# never valid.
ad_group_op2 : AdGroupOperation = client . get_type ( "AdGroupOperation" )
ad_group_op2 . create . name = f "Broken AdGroup: { uuid . uuid4 () } "
ad_group_op2 . create . campaign = invalid_resource_name
ad_group_operations . append ( ad_group_op2 )
# This AdGroup will always fail - duplicate ad group names are not allowed.
ad_group_op3 : AdGroupOperation = client . get_type ( "AdGroupOperation" )
ad_group_op3 . create . name = ad_group_op1 . create . name
ad_group_op3 . create . campaign = resource_name
ad_group_operations . append ( ad_group_op3 )
# Issue a mutate request, setting partial_failure=True.
request : MutateAdGroupsRequest = client . get_type ( "MutateAdGroupsRequest" )
request . customer_id = customer_id
request . operations = ad_group_operations
request . partial_failure = True
return ad_group_service . mutate_ad_groups ( request = request )
Ruby
def add_ad_groups ( customer_id , campaign_id )
# GoogleAdsClient will read a config file from
# ENV['HOME']/google_ads_config.rb when called without parameters
client = Google :: Ads :: GoogleAds :: GoogleAdsClient . new
ad_groups = []
# This ad group should be created successfully.
ad_groups << client . resource . ad_group do | ag |
ag . campaign = client . path . campaign ( customer_id , campaign_id )
ag . name = "Valid ad group: #{ ( Time . new . to_f * 1000 ) . to_i } "
end
# This ad group should fail to create because it references an invalid campaign.
ad_groups << client . resource . ad_group do | ag |
ag . campaign = client . path . campaign ( customer_id , 0 )
ag . name = "Invalid ad group: #{ ( Time . new . to_f * 1000 ) . to_i } "
end
# This ad group should fail to create because it duplicates the name from the first one.
ad_groups << client . resource . ad_group do | ag |
ag . campaign = client . path . campaign ( customer_id , campaign_id )
ag . name = ad_groups . first . name
end
operations = ad_groups . map do | ag |
client . operation . create_resource . ad_group ( ag )
end
response = client . service . ad_group . mutate_ad_groups (
customer_id : customer_id ,
operations : operations ,
partial_failure : true ,
)
response . results . each_with_index do | ad_group , i |
if ad_group . resource_name != ""
puts ( "operations[ #{ i } ] succeeded: Created ad group with id #{ ad_group . resource_name } " )
end
end
failures = client . decode_partial_failure_error ( response . partial_failure_error )
failures . each do | failure |
failure . errors . each do | error |
human_readable_error_path = error
. location
. field_path_elements
. map { | location_info |
if location_info . index
" #{ location_info . field_name } [ #{ location_info . index } ]"
else
" #{ location_info . field_name } "
end
} . join ( " > " )
errmsg = "error occured creating ad group #{ human_readable_error_path } " \
" with value: #{ error . trigger . string_value } " \
" because #{ error . message . downcase } "
puts errmsg
end
end
end . rb
Perl
sub create_ad_groups {
my ( $api_client , $customer_id , $campaign_id ) = @_ ;
my $campaign_resource_name =
Google::Ads::GoogleAds::V22::Utils::ResourceNames:: campaign ( $customer_id ,
$campaign_id );
# This ad group should be created successfully - assuming the campaign in the
# params exists.
my $ad_group1 = Google::Ads::GoogleAds::V22::Resources:: AdGroup - >new ({
name = > "Valid AdGroup: " . uniqid (),
campaign = > $campaign_resource_name
});
# This ad group will always fail - campaign ID 0 in the resource name is never
# valid.
my $ad_group2 = Google::Ads::GoogleAds::V22::Resources:: AdGroup - >new ({
name = > "Broken AdGroup: " . uniqid (),
campaign = > Google::Ads::GoogleAds::V22::Utils::ResourceNames:: campaign (
$customer_id , 0
)});
# This ad group will always fail - duplicate ad group names are not allowed.
my $ad_group3 = Google::Ads::GoogleAds::V22::Resources:: AdGroup - >new ({
name = > $ad_group1 - >{ name },
campaign = > $campaign_resource_name
});
# Create ad group operations.
my $ad_group_operation1 =
Google::Ads::GoogleAds::V22::Services::AdGroupService:: AdGroupOperation - >
new ({ create = > $ad_group1 });
my $ad_group_operation2 =
Google::Ads::GoogleAds::V22::Services::AdGroupService:: AdGroupOperation - >
new ({ create = > $ad_group2 });
my $ad_group_operation3 =
Google::Ads::GoogleAds::V22::Services::AdGroupService:: AdGroupOperation - >
new ({ create = > $ad_group3 });
# Issue the mutate request, enabling partial failure mode.
my $ad_groups_response = $api_client - >AdGroupService () - >mutate ({
customerId = > $customer_id ,
operations = >
[ $ad_group_operation1 , $ad_group_operation2 , $ad_group_operation3 ],
partialFailure = > "true"
});
return $ad_groups_response ;
}
반환된 응답에 부분 오류가 포함되어 있는지 확인
반환된 응답에 부분 실패 오류가 포함되어 있는지 확인하려면 응답의 부분 실패 오류가 비어 있지 않은지 확인하면 됩니다.
자바
private boolean checkIfPartialFailureErrorExists ( MutateAdGroupsResponse response ) {
return response . hasPartialFailureError ();
}
C#
private static bool CheckIfPartialFailureErrorExists ( MutateAdGroupsResponse response )
{
return response . PartialFailureError != null ;
}
PHP
private static function checkIfPartialFailureErrorExists(MutateAdGroupsResponse $response)
{
if ($response->hasPartialFailureError()) {
printf("Partial failures occurred. Details will be shown below.%s", PHP_EOL);
} else {
printf(
"All operations completed successfully. No partial failures to show.%s",
PHP_EOL
);
}
}
Python
def is_partial_failure_error_present ( response : MutateAdGroupsResponse ) - > bool :
"""Checks whether a response message has a partial failure error.
In Python the partial_failure_error attr is always present on a response
message and is represented by a google.rpc.Status message. So we can't
simply check whether the field is present, we must check that the code is
non-zero. Error codes are represented by the google.rpc.Code proto Enum:
https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
Args:
response: A MutateAdGroupsResponse message instance.
Returns: A boolean, whether or not the response message has a partial
failure error.
"""
partial_failure : Any = getattr ( response , "partial_failure_error" , None )
code : int = int ( getattr ( partial_failure , "code" , 0 )) # Default to 0 if None
return code != 0
Ruby
failures = client . decode_partial_failure_error ( response . partial_failure_error )
failures . each do | failure |
failure . errors . each do | error |
human_readable_error_path = error
. location
. field_path_elements
. map { | location_info |
if location_info . index
" #{ location_info . field_name } [ #{ location_info . index } ]"
else
" #{ location_info . field_name } "
end
} . join ( " > " )
errmsg = "error occured creating ad group #{ human_readable_error_path } " \
" with value: #{ error . trigger . string_value } " \
" because #{ error . message . downcase } "
puts errmsg
end
end . rb
Perl
sub check_if_partial_failure_error_exists {
my $ad_groups_response = shift ;
if ( $ad_groups_response - >{ partialFailureError }) {
print "Partial failures occurred. Details will be shown below.\n" ;
} else {
print
"All operations completed successfully. No partial failures to show.\n" ;
}
}
성공한 작업과 실패한 작업 처리
요청의 작업이 성공하면 응답 메시지의 해당 결과(예: MutateAdGroupsResponse의 MutateAdGroupResult)에 일반적으로 리소스 이름이 포함됩니다.
작업이 실패하면 응답 메시지에 partial_failure_error 필드가 채워집니다. 해석 방법은 다음과 같습니다.
partial_failure_error 필드는 google.rpc.Status 유형입니다.
Status.details 필드는 Google Ads API의 부분 실패 오류에 대해 정확히 하나의 요소를 포함하는 목록입니다.
이 단일 요소는 GoogleAdsFailure 의 단일 인스턴스를 패킹하는 Any 프로토입니다. 실패한 작업 수와 관계없이 반환되는 GoogleAdsFailure 객체는 하나뿐입니다.
이 GoogleAdsFailure 객체에는 errors이라는 반복 필드가 포함되어 있습니다. 이 필드는 GoogleAdsError 객체의 목록입니다.
errors 목록의 각 GoogleAdsError는 실패한 작업 중 하나의 특정 오류를 나타냅니다. 여기에는 오류 메시지, 오류 코드, 트리거와 같은 세부정보가 포함됩니다.
특정 GoogleAdsError를 유발한 원래 작업을 식별하려면 GoogleAdsError.location 필드를 검사하면 됩니다.
일반적으로 location.field_path_elements[0].index은 원래 요청에 있는 작업의 0 기반 색인에 해당합니다.
모든 클라이언트 라이브러리는 GoogleAdsFailure 객체를 추출하고 GoogleAdsError 목록을 반복하는 유틸리티 함수를 제공하여 오류 처리를 간소화합니다. 예는 다음 코드 스니펫을 참고하세요.
자바
private void printResults ( MutateAdGroupsResponse response ) {
int operationIndex = 0 ;
for ( MutateAdGroupResult result : response . getResultsList ()) {
if ( ErrorUtils . getInstance (). isPartialFailureResult ( result )) {
// May throw on this line. Most likely this means the wrong version of the ErrorUtils
// class has been used.
GoogleAdsFailure googleAdsFailure = ErrorUtils . getInstance ()
. getGoogleAdsFailure ( response . getPartialFailureError ());
for ( GoogleAdsError error :
ErrorUtils . getInstance ()
. getGoogleAdsErrors ( operationIndex , googleAdsFailure )) {
System . out . printf ( "Operation %d failed with error: %s%n" , operationIndex , error );
}
} else {
System . out . printf ( "Operation %d succeeded.%n" , operationIndex );
}
++ operationIndex ;
}
}
C#
private void PrintResults ( MutateAdGroupsResponse response )
{
// Finds the failed operations by looping through the results.
int operationIndex = 0 ;
foreach ( MutateAdGroupResult result in response . Results )
{
// This represents the result of a failed operation.
if ( result . IsEmpty ())
{
List<GoogleAdsError> errors =
response . PartialFailure . GetErrorsByOperationIndex ( operationIndex );
foreach ( GoogleAdsError error in errors )
{
Console . WriteLine ( $"Operation {operationIndex} failed with " +
$"error: {error}." );
}
}
else
{
Console . WriteLine ( $"Operation {operationIndex} succeeded." ,
operationIndex );
}
operationIndex ++ ;
}
}
PHP
private static function printResults(MutateAdGroupsResponse $response)
{
// Finds the failed operations by looping through the results.
$operationIndex = 0;
foreach ($response->getResults() as $result) {
/** @var AdGroup $result */
if (PartialFailures::isPartialFailure($result)) {
$errors = GoogleAdsErrors::fromStatus(
$operationIndex,
$response->getPartialFailureError()
);
foreach ($errors as $error) {
printf(
"Operation %d failed with error: %s%s",
$operationIndex,
$error->getMessage(),
PHP_EOL
);
}
} else {
printf(
"Operation %d succeeded: ad group with resource name '%s'.%s",
$operationIndex,
$result->getResourceName(),
PHP_EOL
);
}
$operationIndex++;
}
}
Python
def print_results (
client : GoogleAdsClient , response : MutateAdGroupsResponse
) - > None :
"""Prints partial failure errors and success messages from a response.
This function shows how to retrieve partial_failure errors from a response
message (in the case of this example the message will be of type
MutateAdGroupsResponse) and how to unpack those errors to GoogleAdsFailure
instances. It also shows that a response with partial failures may still
contain successful requests, and that those messages should be parsed
separately. As an example, a GoogleAdsFailure object from this example will
be structured similar to:
error_code {
range_error: TOO_LOW
}
message: "Too low."
trigger {
string_value: ""
}
location {
field_path_elements {
field_name: "operations"
index {
value: 1
}
}
field_path_elements {
field_name: "create"
}
field_path_elements {
field_name: "campaign"
}
}
Args:
client: an initialized GoogleAdsClient.
response: a MutateAdGroupsResponse instance.
"""
# Check for existence of any partial failures in the response.
if is_partial_failure_error_present ( response ):
print ( "Partial failures occurred. Details will be shown below. \n " )
# Prints the details of the partial failure errors.
partial_failure : Any = getattr ( response , "partial_failure_error" , None )
# partial_failure_error.details is a repeated field and iterable
error_details : List [ Any ] = getattr ( partial_failure , "details" , [])
for error_detail in error_details :
# Retrieve an instance of the GoogleAdsFailure class from the client
failure_message : Any = client . get_type ( "GoogleAdsFailure" )
# Parse the string into a GoogleAdsFailure message instance.
# To access class-only methods on the message we retrieve its type.
GoogleAdsFailure : Any = type ( failure_message )
failure_object : Any = GoogleAdsFailure . deserialize (
error_detail . value
)
for error in failure_object . errors :
# Construct and print a string that details which element in
# the above ad_group_operations list failed (by index number)
# as well as the error message and error code.
print (
"A partial failure at index "
f " { error . location . field_path_elements [ 0 ] . index } occurred "
f " \n Error message: { error . message } \n Error code: "
f " { error . error_code } "
)
else :
print (
"All operations completed successfully. No partial failure "
"to show."
)
# In the list of results, operations from the ad_group_operation list
# that failed will be represented as empty messages. This loop detects
# such empty messages and ignores them, while printing information about
# successful operations.
for message in response . results :
if not message :
continue
print ( f "Created ad group with resource_name: { message . resource_name } ." )
Ruby
failures = client . decode_partial_failure_error ( response . partial_failure_error )
failures . each do | failure |
failure . errors . each do | error |
human_readable_error_path = error
. location
. field_path_elements
. map { | location_info |
if location_info . index
" #{ location_info . field_name } [ #{ location_info . index } ]"
else
" #{ location_info . field_name } "
end
} . join ( " > " )
errmsg = "error occured creating ad group #{ human_readable_error_path } " \
" with value: #{ error . trigger . string_value } " \
" because #{ error . message . downcase } "
puts errmsg
end
end . rb
Perl
sub print_results {
my $ad_groups_response = shift ;
# Find the failed operations by looping through the results.
while ( my ( $operation_index , $result ) =
each @ { $ad_groups_response - >{ results }})
{
if ( is_partial_failure_result ( $result )) {
my $google_ads_errors = get_google_ads_errors ( $operation_index ,
$ad_groups_response - >{ partialFailureError });
foreach my $google_ads_error ( @$google_ads_errors ) {
printf "Operation %d failed with error: %s\n" , $operation_index ,
$google_ads_error - >{ message };
}
} else {
printf "Operation %d succeeded: ad group with resource name '%s'.\n" ,
$operation_index , $result - >{ resourceName };
}
}
}
비동기 작업의 부분 실패
OfflineUserDataJob 과 같은 비동기 작업에 부분 실패를 사용하는 경우 일부 또는 모든 작업이 작업에 추가되지 않더라도 작업이 SUCCESS 상태를 반환할 수 있다는 점에 유의해야 합니다.
부분 실패가 사용 설정된 경우 OfflineUserDataJob에 작업을 추가하려고 하는데 일부 작업이 잘못되면 해당 작업은 AddOfflineUserDataJobOperationsResponse 의 partial_failure_error 필드에 오류를 반환하지만 유효한 작업은 작업에 추가됩니다. 모든 작업이 유효하지 않으면 partial_failure_error가 채워지지만 작업에 작업이 추가되지 않습니다.
RunOfflineUserDataJob 로 작업을 실행하고 작업에 작업이 포함되지 않은 경우(예: 작업이 유효하지 않아 작업에 추가되지 않음) SUCCESS 상태로 완료됩니다.
OfflineUserDataJob에 작업을 추가할 때 부분 실패를 사용하는 경우 AddOfflineUserDataJobOperationsResponse에서 partial_failure_error 필드를 확인해야 합니다. 이 필드가 채워져 있으면 일부 또는 모든 작업이 작업에 추가되지 않았음을 의미합니다.
코드 예시
각 클라이언트 라이브러리 의 ErrorHandling 폴더에는 이 기능을 사용하는 방법을 보여주는 다음 코드 예가 포함되어 있습니다.
자바
// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.ads.googleads.examples.errorhandling ;
import static com.google.ads.googleads.examples.utils.CodeSampleHelper.getPrintableDateTime ;
import com.beust.jcommander.Parameter ;
import com.google.ads.googleads.examples.utils.ArgumentNames ;
import com.google.ads.googleads.examples.utils.CodeSampleParams ;
import com.google.ads.googleads.lib.GoogleAdsClient ;
import com.google.ads.googleads.v22.errors.GoogleAdsError ;
import com.google.ads.googleads.v22.errors.GoogleAdsException ;
import com.google.ads.googleads.v22.errors.GoogleAdsFailure ;
import com.google.ads.googleads.v22.resources.AdGroup ;
import com.google.ads.googleads.v22.services.AdGroupOperation ;
import com.google.ads.googleads.v22.services.AdGroupServiceClient ;
import com.google.ads.googleads.v22.services.MutateAdGroupResult ;
import com.google.ads.googleads.v22.services.MutateAdGroupsRequest ;
import com.google.ads.googleads.v22.services.MutateAdGroupsResponse ;
import com.google.ads.googleads.v22.utils.ErrorUtils ;
import com.google.ads.googleads.v22.utils.ResourceNames ;
import java.io.FileNotFoundException ;
import java.io.IOException ;
import java.util.Arrays ;
/**
* Shows how to handle partial failures. There are several ways of detecting partial failures. This
* highlights the top main detection options: empty results and error instances.
*
* <p>Access to the detailed error (<code>GoogleAdsFailure</code>) for each error is via a Any
* proto. Deserializing these to retrieve the error details is may not be immediately obvious at
* first, this example shows how to convert Any into <code>GoogleAdsFailure</code>.
*
* <p>Additionally, this example shows how to produce an error message for a specific failed
* operation by looking up the failure details in the <code>GoogleAdsFailure</code> object.
*/
public class HandlePartialFailure {
private static class HandlePartialFailureParams extends CodeSampleParams {
@Parameter ( names = ArgumentNames . CUSTOMER_ID , required = true )
private Long customerId ;
@Parameter ( names = ArgumentNames . CAMPAIGN_ID , required = true )
private Long campaignId ;
}
public static void main ( String [] args ) {
HandlePartialFailureParams params = new HandlePartialFailureParams ();
if ( ! params . parseArguments ( args )) {
// Either pass the required parameters for this example on the command line, or insert them
// into the code here. See the parameter class definition above for descriptions.
params . customerId = Long . parseLong ( "INSERT_CUSTOMER_ID" );
params . campaignId = Long . parseLong ( "INSERT_CAMPAIGN_ID" );
}
GoogleAdsClient googleAdsClient = null ;
try {
googleAdsClient = GoogleAdsClient . newBuilder (). fromPropertiesFile (). build ();
} catch ( FileNotFoundException fnfe ) {
System . err . printf (
"Failed to load GoogleAdsClient configuration from file. Exception: %s%n" , fnfe );
System . exit ( 1 );
} catch ( IOException ioe ) {
System . err . printf ( "Failed to create GoogleAdsClient. Exception: %s%n" , ioe );
System . exit ( 1 );
}
try {
new HandlePartialFailure (). runExample ( googleAdsClient , params . customerId , params . campaignId );
} catch ( GoogleAdsException gae ) {
// GoogleAdsException is the base class for most exceptions thrown by an API request.
// Instances of this exception have a message and a GoogleAdsFailure that contains a
// collection of GoogleAdsErrors that indicate the underlying causes of the
// GoogleAdsException.
System . err . printf (
"Request ID %s failed due to GoogleAdsException. Underlying errors:%n" ,
gae . getRequestId ());
int i = 0 ;
for ( GoogleAdsError googleAdsError : gae . getGoogleAdsFailure (). getErrorsList ()) {
System . err . printf ( " Error %d: %s%n" , i ++ , googleAdsError );
}
System . exit ( 1 );
}
}
/** Runs the example. */
public void runExample ( GoogleAdsClient googleAdsClient , long customerId , long campaignId ) {
MutateAdGroupsResponse response = createAdGroups ( googleAdsClient , customerId , campaignId );
// Checks for existence of any partial failures in the response.
if ( checkIfPartialFailureErrorExists ( response )) {
System . out . println ( "Partial failures occurred." );
} else {
System . out . println ( "All operations completed successfully. No partial failures to show." );
return ;
}
// Finds the failed operations by looping through the results.
printResults ( response );
}
/**
* Attempts to create 3 ad groups with partial failure enabled. One of the ad groups will succeed,
* while the other will fail.
*/
private MutateAdGroupsResponse createAdGroups (
GoogleAdsClient googleAdsClient , long customerId , long campaignId ) {
// This AdGroup should be created successfully - assuming the campaign in the params exists.
AdGroup group1 =
AdGroup . newBuilder ()
. setCampaign ( ResourceNames . campaign ( customerId , campaignId ))
. setName ( "Valid AdGroup: " + getPrintableDateTime ())
. build ();
// This AdGroup will always fail - campaign ID 0 in resource names is never valid.
AdGroup group2 =
AdGroup . newBuilder ()
. setCampaign ( ResourceNames . campaign ( customerId , 0 L ))
. setName ( "Broken AdGroup: " + getPrintableDateTime ())
. build ();
// This AdGroup will always fail - duplicate ad group names are not allowed.
AdGroup group3 =
AdGroup . newBuilder ()
. setCampaign ( ResourceNames . campaign ( customerId , campaignId ))
. setName ( group1 . getName ())
. build ();
AdGroupOperation op1 = AdGroupOperation . newBuilder (). setCreate ( group1 ). build ();
AdGroupOperation op2 = AdGroupOperation . newBuilder (). setCreate ( group2 ). build ();
AdGroupOperation op3 = AdGroupOperation . newBuilder (). setCreate ( group3 ). build ();
try ( AdGroupServiceClient service =
googleAdsClient . getLatestVersion (). createAdGroupServiceClient ()) {
// Issues the mutate request, setting partialFailure=true.
return service . mutateAdGroups (
MutateAdGroupsRequest . newBuilder ()
. setCustomerId ( String . valueOf ( customerId ))
. setCustomerId ( Long . toString ( customerId ))
. addAllOperations ( Arrays . asList ( op1 , op2 , op3 ))
. setPartialFailure ( true )
. build ());
}
}
/** Inspects a response to check for presence of partial failure errors. */
private boolean checkIfPartialFailureErrorExists ( MutateAdGroupsResponse response ) {
return response . hasPartialFailureError ();
}
/** Displays the result from the mutate operation. */
private void printResults ( MutateAdGroupsResponse response ) {
int operationIndex = 0 ;
for ( MutateAdGroupResult result : response . getResultsList ()) {
if ( ErrorUtils . getInstance (). isPartialFailureResult ( result )) {
// May throw on this line. Most likely this means the wrong version of the ErrorUtils
// class has been used.
GoogleAdsFailure googleAdsFailure = ErrorUtils . getInstance ()
. getGoogleAdsFailure ( response . getPartialFailureError ());
for ( GoogleAdsError error :
ErrorUtils . getInstance ()
. getGoogleAdsErrors ( operationIndex , googleAdsFailure )) {
System . out . printf ( "Operation %d failed with error: %s%n" , operationIndex , error );
}
} else {
System . out . printf ( "Operation %d succeeded.%n" , operationIndex );
}
++ operationIndex ;
}
}
}
C#
// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using CommandLine ;
using Google.Ads.Gax.Examples ;
using Google.Ads.Gax.Lib ;
using Google.Ads.GoogleAds.Lib ;
using Google.Ads.GoogleAds.V22.Errors ;
using Google.Ads.GoogleAds.V22.Resources ;
using Google.Ads.GoogleAds.V22.Services ;
using System ;
using System.Collections.Generic ;
namespace Google.Ads.GoogleAds.Examples.V22
{
/// <summary>
/// This code example demonstrates how to handle partial failures.
/// </summary>
public class HandlePartialFailure : ExampleBase
{
/// <summary>
/// Command line options for running the <see cref="HandlePartialFailure"/> example.
/// </summary>
public class Options : OptionsBase
{
/// <summary>
/// The customer ID for which the call is made.
/// </summary>
[Option("customerId", Required = true, HelpText =
"The customer ID for which the call is made.")]
public long CustomerId { get ; set ; }
/// <summary>
/// ID of the campaign to which ad groups are added.
/// </summary>
[Option("campaignId", Required = true, HelpText =
"ID of the campaign to which ad groups are added.")]
public long CampaignId { get ; set ; }
}
/// <summary>
/// Main method, to run this code example as a standalone application.
/// </summary>
/// <param name="args">The command line arguments.</param>
public static void Main ( string [] args )
{
Options options = ExampleUtilities . ParseCommandLine<Options> ( args );
HandlePartialFailure codeExample = new HandlePartialFailure ();
Console . WriteLine ( codeExample . Description );
codeExample . Run ( new GoogleAdsClient (), options . CustomerId , options . CampaignId );
}
/// <summary>
/// Returns a description about the code example.
/// </summary>
public override string Description = >
"This code example demonstrates how to handle partial failures." ;
/// <summary>
/// Runs the code example.
/// </summary>
/// <param name="client">The Google Ads client.</param>
/// <param name="customerId">The customer ID for which the call is made.</param>
/// <param name="campaignId">ID of the campaign to which ad groups are added.</param>
public void Run ( GoogleAdsClient client , long customerId , long campaignId )
{
try
{
MutateAdGroupsResponse response = CreateAdGroups ( client , customerId , campaignId );
// Checks for existence of any partial failures in the response.
if ( CheckIfPartialFailureErrorExists ( response ))
{
Console . WriteLine ( "Partial failures occurred. Details will be shown below." );
}
else
{
Console . WriteLine ( "All operations completed successfully. No partial " +
"failures to show." );
return ;
}
// Finds the failed operations by looping through the results.
PrintResults ( response );
}
catch ( GoogleAdsException e )
{
Console . WriteLine ( "Failure:" );
Console . WriteLine ( $"Message: {e.Message}" );
Console . WriteLine ( $"Failure: {e.Failure}" );
Console . WriteLine ( $"Request ID: {e.RequestId}" );
throw ;
}
}
/// <summary>
/// Displays the result from the mutate operation.
/// </summary>
/// <param name="response">The mutate response from the Google Ads API server..</param>
private void PrintResults ( MutateAdGroupsResponse response )
{
// Finds the failed operations by looping through the results.
int operationIndex = 0 ;
foreach ( MutateAdGroupResult result in response . Results )
{
// This represents the result of a failed operation.
if ( result . IsEmpty ())
{
List<GoogleAdsError> errors =
response . PartialFailure . GetErrorsByOperationIndex ( operationIndex );
foreach ( GoogleAdsError error in errors )
{
Console . WriteLine ( $"Operation {operationIndex} failed with " +
$"error: {error}." );
}
}
else
{
Console . WriteLine ( $"Operation {operationIndex} succeeded." ,
operationIndex );
}
operationIndex ++ ;
}
}
/// <summary>
/// Inspects a response to check for presence of partial failure errors.
/// </summary>
/// <param name="response">The response.</param>
/// <returns>True if there are partial failures, false otherwise.</returns>
private static bool CheckIfPartialFailureErrorExists ( MutateAdGroupsResponse response )
{
return response . PartialFailureError != null ;
}
/// <summary>
/// Attempts to create 3 ad groups with partial failure enabled. One of the ad groups
/// will succeed, while the other will fail.
/// </summary>
/// <param name="client">The Google Ads client.</param>
/// <param name="customerId">The customer ID for which the call is made.</param>
/// <param name="campaignId">ID of the campaign to which ad groups are added.</param>
/// <returns>The mutate response from the Google Ads server.</returns>
private static MutateAdGroupsResponse CreateAdGroups ( GoogleAdsClient client ,
long customerId , long campaignId )
{
// Get the AdGroupServiceClient.
AdGroupServiceClient adGroupService = client . GetService ( Services . V22 . AdGroupService );
string validAdGroupName = "Valid AdGroup: " + ExampleUtilities . GetRandomString ();
AdGroupOperation [] operations = new AdGroupOperation []
{
// This operation will be successful, assuming the campaign specified in
// campaignId parameter is correct.
new AdGroupOperation ()
{
Create = new AdGroup ()
{
Campaign = ResourceNames . Campaign ( customerId , campaignId ),
Name = validAdGroupName
}
},
// This operation will fail since we are using campaign ID = 0, which results
// in an invalid resource name.
new AdGroupOperation ()
{
Create = new AdGroup ()
{
Campaign = ResourceNames . Campaign ( customerId , 0 ),
Name = "Broken AdGroup: " + ExampleUtilities . GetRandomString ()
},
},
// This operation will fail since the ad group is using the same name as the ad
// group from the first operation. Duplicate ad group names are not allowed.
new AdGroupOperation ()
{
Create = new AdGroup ()
{
Campaign = ResourceNames . Campaign ( customerId , campaignId ),
Name = validAdGroupName
}
}
};
// Add the ad groups.
MutateAdGroupsResponse response =
adGroupService . MutateAdGroups ( new MutateAdGroupsRequest ()
{
CustomerId = customerId . ToString (),
Operations = { operations },
PartialFailure = true ,
ValidateOnly = false
});
return response ;
}
}
}
PHP
<?php
/**
* Copyright 2019 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace Google\Ads\GoogleAds\Examples\ErrorHandling;
require __DIR__ . '/../../vendor/autoload.php';
use GetOpt\GetOpt;
use Google\Ads\GoogleAds\Examples\Utils\ArgumentNames;
use Google\Ads\GoogleAds\Examples\Utils\ArgumentParser;
use Google\Ads\GoogleAds\Examples\Utils\Helper;
use Google\Ads\GoogleAds\Lib\V22\GoogleAdsClient;
use Google\Ads\GoogleAds\Lib\V22\GoogleAdsClientBuilder;
use Google\Ads\GoogleAds\Lib\V22\GoogleAdsException;
use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder;
use Google\Ads\GoogleAds\Util\V22\GoogleAdsErrors;
use Google\Ads\GoogleAds\Util\V22\PartialFailures;
use Google\Ads\GoogleAds\Util\V22\ResourceNames;
use Google\Ads\GoogleAds\V22\Errors\GoogleAdsError;
use Google\Ads\GoogleAds\V22\Resources\AdGroup;
use Google\Ads\GoogleAds\V22\Services\AdGroupOperation;
use Google\Ads\GoogleAds\V22\Services\MutateAdGroupsRequest;
use Google\Ads\GoogleAds\V22\Services\MutateAdGroupsResponse;
use Google\ApiCore\ApiException;
/**
* Shows how to handle partial failures. There are several ways of detecting partial failures. This
* highlights the top main detection options: empty results and error instances.
*
* <p>Access to the detailed error (<code>GoogleAdsFailure</code>) for each error is via a Any
* proto. Deserializing these to retrieve the error details is may not be immediately obvious at
* first, this example shows how to convert Any into <code>GoogleAdsFailure</code>.
*
* <p>Additionally, this example shows how to produce an error message for a specific failed
* operation by looking up the failure details in the <code>GoogleAdsFailure</code> object.
*/
class HandlePartialFailure
{
private const CUSTOMER_ID = 'INSERT_CUSTOMER_ID_HERE';
private const CAMPAIGN_ID = 'INSERT_CAMPAIGN_ID_HERE';
public static function main()
{
// Either pass the required parameters for this example on the command line, or insert them
// into the constants above.
$options = (new ArgumentParser())->parseCommandArguments([
ArgumentNames::CUSTOMER_ID => GetOpt::REQUIRED_ARGUMENT,
ArgumentNames::CAMPAIGN_ID => GetOpt::REQUIRED_ARGUMENT
]);
// Generate a refreshable OAuth2 credential for authentication.
$oAuth2Credential = (new OAuth2TokenBuilder())->fromFile()->build();
// Construct a Google Ads client configured from a properties file and the
// OAuth2 credentials above.
$googleAdsClient = (new GoogleAdsClientBuilder())
->fromFile()
->withOAuth2Credential($oAuth2Credential)
->build();
try {
self::runExample(
$googleAdsClient,
$options[ArgumentNames::CUSTOMER_ID] ?: self::CUSTOMER_ID,
$options[ArgumentNames::CAMPAIGN_ID] ?: self::CAMPAIGN_ID
);
} catch (GoogleAdsException $googleAdsException) {
printf(
"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 */
printf(
"\t%s: %s%s",
$error->getErrorCode()->getErrorCode(),
$error->getMessage(),
PHP_EOL
);
}
exit(1);
} catch (ApiException $apiException) {
printf(
"ApiException was thrown with message '%s'.%s",
$apiException->getMessage(),
PHP_EOL
);
exit(1);
}
}
/**
* Runs the example.
*
* @param GoogleAdsClient $googleAdsClient the Google Ads API client
* @param int $customerId the customer ID
* @param int $campaignId a campaign ID
*/
public static function runExample(
GoogleAdsClient $googleAdsClient,
int $customerId,
int $campaignId
) {
$response = self::createAdGroups($googleAdsClient, $customerId, $campaignId);
self::checkIfPartialFailureErrorExists($response);
self::printResults($response);
}
/**
* Create ad groups by enabling partial failure mode.
*
* @param GoogleAdsClient $googleAdsClient the Google Ads API client
* @param int $customerId the customer ID
* @param int $campaignId a campaign ID
* @return MutateAdGroupsResponse
*/
private static function createAdGroups(
GoogleAdsClient $googleAdsClient,
int $customerId,
int $campaignId
) {
$campaignResourceName = ResourceNames::forCampaign($customerId, $campaignId);
// This ad group should be created successfully - assuming the campaign in the params
// exists.
$adGroup1 = new AdGroup([
'name' => 'Valid AdGroup #' . Helper::getPrintableDatetime(),
'campaign' => $campaignResourceName
]);
// This ad group will always fail - campaign ID 0 in the resource name is never valid.
$adGroup2 = new AdGroup([
'name' => 'Broken AdGroup #' . Helper::getPrintableDatetime(),
'campaign' => ResourceNames::forCampaign($customerId, 0)
]);
// This ad group will always fail - duplicate ad group names are not allowed.
$adGroup3 = new AdGroup([
'name' => $adGroup1->getName(),
'campaign' => $campaignResourceName
]);
$operations = [];
$adGroupOperation1 = new AdGroupOperation();
$adGroupOperation1->setCreate($adGroup1);
$operations[] = $adGroupOperation1;
$adGroupOperation2 = new AdGroupOperation();
$adGroupOperation2->setCreate($adGroup2);
$operations[] = $adGroupOperation2;
$adGroupOperation3 = new AdGroupOperation();
$adGroupOperation3->setCreate($adGroup3);
$operations[] = $adGroupOperation3;
// Issues the mutate request, enabling partial failure mode.
$adGroupServiceClient = $googleAdsClient->getAdGroupServiceClient();
return $adGroupServiceClient->mutateAdGroups(
MutateAdGroupsRequest::build($customerId, $operations)->setPartialFailure(true)
);
}
/**
* Check if there exists partial failure error in the given mutate ad group response.
*
* @param MutateAdGroupsResponse $response the mutate ad group response
*/
private static function checkIfPartialFailureErrorExists(MutateAdGroupsResponse $response)
{
if ($response->hasPartialFailureError()) {
printf("Partial failures occurred. Details will be shown below.%s", PHP_EOL);
} else {
printf(
"All operations completed successfully. No partial failures to show.%s",
PHP_EOL
);
}
}
/**
* Print results of the given mutate ad group response. For those that are partial failure,
* print all their errors with corresponding operation indices. For those that succeeded, print
* the resource names of created ad groups.
*
* @param MutateAdGroupsResponse $response the mutate ad group response
*/
private static function printResults(MutateAdGroupsResponse $response)
{
// Finds the failed operations by looping through the results.
$operationIndex = 0;
foreach ($response->getResults() as $result) {
/** @var AdGroup $result */
if (PartialFailures::isPartialFailure($result)) {
$errors = GoogleAdsErrors::fromStatus(
$operationIndex,
$response->getPartialFailureError()
);
foreach ($errors as $error) {
printf(
"Operation %d failed with error: %s%s",
$operationIndex,
$error->getMessage(),
PHP_EOL
);
}
} else {
printf(
"Operation %d succeeded: ad group with resource name '%s'.%s",
$operationIndex,
$result->getResourceName(),
PHP_EOL
);
}
$operationIndex++;
}
}
}
HandlePartialFailure::main();
Python
#!/usr/bin/env python
# Copyright 2018 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""This shows how to handle responses that may include partial_failure errors."""
import argparse
import sys
import uuid
from typing import Any , List
from google.ads.googleads.client import GoogleAdsClient
from google.ads.googleads.errors import GoogleAdsException
from google.ads.googleads.v22.services.services.ad_group_service import (
AdGroupServiceClient ,
)
from google.ads.googleads.v22.services.services.campaign_service import (
CampaignServiceClient ,
)
from google.ads.googleads.v22.services.types.ad_group_service import (
AdGroupOperation ,
MutateAdGroupsResponse ,
MutateAdGroupsRequest ,
)
def main ( client : GoogleAdsClient , customer_id : str , campaign_id : str ) - > None :
"""Runs the example code, which demonstrates how to handle partial failures.
The example creates three Ad Groups, two of which intentionally fail in
order to generate a partial failure error. It also demonstrates how to
properly identify a partial error and how to log the error messages.
Args:
client: An initialized GoogleAdsClient instance.
customer_id: A valid customer account ID.
campaign_id: The ID for a campaign to create Ad Groups under.
"""
try :
ad_group_response : MutateAdGroupsResponse = create_ad_groups (
client , customer_id , campaign_id
)
except GoogleAdsException as ex :
print (
f 'Request with ID " { ex . request_id } " failed with status '
f '" { ex . error . code () . name } " and includes the following errors:'
)
for error in ex . failure . errors :
print ( f ' \t Error with message " { error . message } ".' )
if error . location :
for field_path_element in error . location . field_path_elements :
print ( f " \t\t On field: { field_path_element . field_name } " )
sys . exit ( 1 )
else :
print_results ( client , ad_group_response )
def create_ad_groups (
client : GoogleAdsClient , customer_id : str , campaign_id : str
) - > MutateAdGroupsResponse :
"""Creates three Ad Groups, two of which intentionally generate errors.
Args:
client: An initialized GoogleAdsClient instance.
customer_id: A valid customer account ID.
campaign_id: The ID for a campaign to create Ad Groups under.
Returns: A MutateAdGroupsResponse message instance.
"""
ad_group_service : AdGroupServiceClient = client . get_service (
"AdGroupService"
)
campaign_service : CampaignServiceClient = client . get_service (
"CampaignService"
)
resource_name : str = campaign_service . campaign_path (
customer_id , campaign_id
)
invalid_resource_name : str = campaign_service . campaign_path ( customer_id , 0 )
ad_group_operations : List [ AdGroupOperation ] = []
# This AdGroup should be created successfully - assuming the campaign in
# the params exists.
ad_group_op1 : AdGroupOperation = client . get_type ( "AdGroupOperation" )
ad_group_op1 . create . name = f "Valid AdGroup: { uuid . uuid4 () } "
ad_group_op1 . create . campaign = resource_name
ad_group_operations . append ( ad_group_op1 )
# This AdGroup will always fail - campaign ID 0 in resource names is
# never valid.
ad_group_op2 : AdGroupOperation = client . get_type ( "AdGroupOperation" )
ad_group_op2 . create . name = f "Broken AdGroup: { uuid . uuid4 () } "
ad_group_op2 . create . campaign = invalid_resource_name
ad_group_operations . append ( ad_group_op2 )
# This AdGroup will always fail - duplicate ad group names are not allowed.
ad_group_op3 : AdGroupOperation = client . get_type ( "AdGroupOperation" )
ad_group_op3 . create . name = ad_group_op1 . create . name
ad_group_op3 . create . campaign = resource_name
ad_group_operations . append ( ad_group_op3 )
# Issue a mutate request, setting partial_failure=True.
request : MutateAdGroupsRequest = client . get_type ( "MutateAdGroupsRequest" )
request . customer_id = customer_id
request . operations = ad_group_operations
request . partial_failure = True
return ad_group_service . mutate_ad_groups ( request = request )
def is_partial_failure_error_present ( response : MutateAdGroupsResponse ) - > bool :
"""Checks whether a response message has a partial failure error.
In Python the partial_failure_error attr is always present on a response
message and is represented by a google.rpc.Status message. So we can't
simply check whether the field is present, we must check that the code is
non-zero. Error codes are represented by the google.rpc.Code proto Enum:
https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto
Args:
response: A MutateAdGroupsResponse message instance.
Returns: A boolean, whether or not the response message has a partial
failure error.
"""
partial_failure : Any = getattr ( response , "partial_failure_error" , None )
code : int = int ( getattr ( partial_failure , "code" , 0 )) # Default to 0 if None
return code != 0
def print_results (
client : GoogleAdsClient , response : MutateAdGroupsResponse
) - > None :
"""Prints partial failure errors and success messages from a response.
This function shows how to retrieve partial_failure errors from a response
message (in the case of this example the message will be of type
MutateAdGroupsResponse) and how to unpack those errors to GoogleAdsFailure
instances. It also shows that a response with partial failures may still
contain successful requests, and that those messages should be parsed
separately. As an example, a GoogleAdsFailure object from this example will
be structured similar to:
error_code {
range_error: TOO_LOW
}
message: "Too low."
trigger {
string_value: ""
}
location {
field_path_elements {
field_name: "operations"
index {
value: 1
}
}
field_path_elements {
field_name: "create"
}
field_path_elements {
field_name: "campaign"
}
}
Args:
client: an initialized GoogleAdsClient.
response: a MutateAdGroupsResponse instance.
"""
# Check for existence of any partial failures in the response.
if is_partial_failure_error_present ( response ):
print ( "Partial failures occurred. Details will be shown below. \n " )
# Prints the details of the partial failure errors.
partial_failure : Any = getattr ( response , "partial_failure_error" , None )
# partial_failure_error.details is a repeated field and iterable
error_details : List [ Any ] = getattr ( partial_failure , "details" , [])
for error_detail in error_details :
# Retrieve an instance of the GoogleAdsFailure class from the client
failure_message : Any = client . get_type ( "GoogleAdsFailure" )
# Parse the string into a GoogleAdsFailure message instance.
# To access class-only methods on the message we retrieve its type.
GoogleAdsFailure : Any = type ( failure_message )
failure_object : Any = GoogleAdsFailure . deserialize (
error_detail . value
)
for error in failure_object . errors :
# Construct and print a string that details which element in
# the above ad_group_operations list failed (by index number)
# as well as the error message and error code.
print (
"A partial failure at index "
f " { error . location . field_path_elements [ 0 ] . index } occurred "
f " \n Error message: { error . message } \n Error code: "
f " { error . error_code } "
)
else :
print (
"All operations completed successfully. No partial failure "
"to show."
)
# In the list of results, operations from the ad_group_operation list
# that failed will be represented as empty messages. This loop detects
# such empty messages and ignores them, while printing information about
# successful operations.
for message in response . results :
if not message :
continue
print ( f "Created ad group with resource_name: { message . resource_name } ." )
if __name__ == "__main__" :
parser = argparse . ArgumentParser (
description = "Adds an ad group for specified customer and campaign id."
)
# The following argument(s) should be provided to run the example.
parser . add_argument (
"-c" ,
"--customer_id" ,
type = str ,
required = True ,
help = "The Google Ads customer ID." ,
)
parser . add_argument (
"-i" , "--campaign_id" , type = str , required = True , help = "The campaign ID."
)
args = parser . parse_args ()
# GoogleAdsClient will read the google-ads.yaml configuration file in the
# home directory if none is specified.
googleads_client : GoogleAdsClient = GoogleAdsClient . load_from_storage (
version = "v22"
)
main ( googleads_client , args . customer_id , args . campaign_id )
Ruby
# Encoding: utf-8
#
# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# This code example shows how to deal with partial failures
require 'optparse'
require 'google/ads/google_ads'
require 'date'
def add_ad_groups ( customer_id , campaign_id )
# GoogleAdsClient will read a config file from
# ENV['HOME']/google_ads_config.rb when called without parameters
client = Google :: Ads :: GoogleAds :: GoogleAdsClient . new
ad_groups = []
# This ad group should be created successfully.
ad_groups << client . resource . ad_group do | ag |
ag . campaign = client . path . campaign ( customer_id , campaign_id )
ag . name = "Valid ad group: #{ ( Time . new . to_f * 1000 ) . to_i } "
end
# This ad group should fail to create because it references an invalid campaign.
ad_groups << client . resource . ad_group do | ag |
ag . campaign = client . path . campaign ( customer_id , 0 )
ag . name = "Invalid ad group: #{ ( Time . new . to_f * 1000 ) . to_i } "
end
# This ad group should fail to create because it duplicates the name from the first one.
ad_groups << client . resource . ad_group do | ag |
ag . campaign = client . path . campaign ( customer_id , campaign_id )
ag . name = ad_groups . first . name
end
operations = ad_groups . map do | ag |
client . operation . create_resource . ad_group ( ag )
end
response = client . service . ad_group . mutate_ad_groups (
customer_id : customer_id ,
operations : operations ,
partial_failure : true ,
)
response . results . each_with_index do | ad_group , i |
if ad_group . resource_name != ""
puts ( "operations[ #{ i } ] succeeded: Created ad group with id #{ ad_group . resource_name } " )
end
end
failures = client . decode_partial_failure_error ( response . partial_failure_error )
failures . each do | failure |
failure . errors . each do | error |
human_readable_error_path = error
. location
. field_path_elements
. map { | location_info |
if location_info . index
" #{ location_info . field_name } [ #{ location_info . index } ]"
else
" #{ location_info . field_name } "
end
} . join ( " > " )
errmsg = "error occured creating ad group #{ human_readable_error_path } " \
" with value: #{ error . trigger . string_value } " \
" because #{ error . message . downcase } "
puts errmsg
end
end
end
if __FILE__ == $PROGRAM_NAME
options = {}
# The following parameter(s) should be provided to run the example. You can
# either specify these by changing the INSERT_XXX_ID_HERE values below, or on
# the command line.
#
# Parameters passed on the command line will override any parameters set in
# code.
#
# Running the example with -h will print the command line usage.
options [ :customer_id ] = 'INSERT_CUSTOMER_ID_HERE'
options [ :campaign_id ] = 'INSERT_CAMPAIGN_ID_HERE'
OptionParser . new do | opts |
opts . banner = sprintf ( 'Usage: ruby %s [options]' , File . basename ( __FILE__ ))
opts . separator ''
opts . separator 'Options:'
opts . on ( '-C' , '--customer-id CUSTOMER-ID' , String , 'Customer ID' ) do | v |
options [ :customer_id ] = v
end
opts . on ( '-c' , '--campaign-id CAMPAIGN-ID' , String , 'Ad Group ID' ) do | v |
options [ :campaign_id ] = v
end
opts . separator ''
opts . separator 'Help:'
opts . on_tail ( '-h' , '--help' , 'Show this message' ) do
puts opts
exit
end
end . parse!
begin
add_ad_groups (
options . fetch ( :customer_id ) . tr ( "-" , "" ),
options . fetch ( :campaign_id ),
)
rescue Google :: Ads :: GoogleAds :: Errors :: GoogleAdsError = > e
e . failure . errors . each do | error |
STDERR . printf ( "Error with message: %s \n " , error . message )
if error . location
error . location . field_path_elements . each do | field_path_element |
STDERR . printf ( " \t On field: %s \n " , field_path_element . field_name )
end
end
error . error_code . to_h . each do | k , v |
next if v == :UNSPECIFIED
STDERR . printf ( " \t Type: %s \n\t Code: %s \n " , k , v )
end
end
raise
end
end
Perl
#!/usr/bin/perl -w
#
# Copyright 2019, Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# This example shows how to deal with partial failures. There are several ways
# of detecting partial failures. This example highlights the top main detection
# options: empty results and error instances.
use strict ;
use warnings ;
use utf8 ;
use FindBin qw($Bin) ;
use lib "$Bin/../../lib" ;
use Google::Ads::GoogleAds::Client ;
use Google::Ads::GoogleAds::Utils::GoogleAdsHelper ;
use Google::Ads::GoogleAds::Utils::PartialFailureUtils ;
use Google::Ads::GoogleAds::V22::Resources::AdGroup ;
use Google::Ads::GoogleAds::V22::Services::AdGroupService::AdGroupOperation ;
use Google::Ads::GoogleAds::V22::Utils::ResourceNames ;
use Getopt::Long qw(:config auto_help) ;
use Pod::Usage ;
use Cwd qw(abs_path) ;
use Data::Uniqid qw(uniqid) ;
# The following parameter(s) should be provided to run the example. You can
# either specify these by changing the INSERT_XXX_ID_HERE values below, or on
# the command line.
#
# Parameters passed on the command line will override any parameters set in
# code.
#
# Running the example with -h will print the command line usage.
my $customer_id = "INSERT_CUSTOMER_ID_HERE" ;
my $campaign_id = "INSERT_CAMPAIGN_ID_HERE" ;
sub handle_partial_failure {
my ( $api_client , $customer_id , $campaign_id ) = @_ ;
my $ad_groups_response =
create_ad_groups ( $api_client , $customer_id , $campaign_id );
check_if_partial_failure_error_exists ( $ad_groups_response );
print_results ( $ad_groups_response );
return 1 ;
}
# Creates ad groups by enabling partial failure mode.
sub create_ad_groups {
my ( $api_client , $customer_id , $campaign_id ) = @_ ;
my $campaign_resource_name =
Google::Ads::GoogleAds::V22::Utils::ResourceNames:: campaign ( $customer_id ,
$campaign_id );
# This ad group should be created successfully - assuming the campaign in the
# params exists.
my $ad_group1 = Google::Ads::GoogleAds::V22::Resources:: AdGroup - >new ({
name = > "Valid AdGroup: " . uniqid (),
campaign = > $campaign_resource_name
});
# This ad group will always fail - campaign ID 0 in the resource name is never
# valid.
my $ad_group2 = Google::Ads::GoogleAds::V22::Resources:: AdGroup - >new ({
name = > "Broken AdGroup: " . uniqid (),
campaign = > Google::Ads::GoogleAds::V22::Utils::ResourceNames:: campaign (
$customer_id , 0
)});
# This ad group will always fail - duplicate ad group names are not allowed.
my $ad_group3 = Google::Ads::GoogleAds::V22::Resources:: AdGroup - >new ({
name = > $ad_group1 - >{ name },
campaign = > $campaign_resource_name
});
# Create ad group operations.
my $ad_group_operation1 =
Google::Ads::GoogleAds::V22::Services::AdGroupService:: AdGroupOperation - >
new ({ create = > $ad_group1 });
my $ad_group_operation2 =
Google::Ads::GoogleAds::V22::Services::AdGroupService:: AdGroupOperation - >
new ({ create = > $ad_group2 });
my $ad_group_operation3 =
Google::Ads::GoogleAds::V22::Services::AdGroupService:: AdGroupOperation - >
new ({ create = > $ad_group3 });
# Issue the mutate request, enabling partial failure mode.
my $ad_groups_response = $api_client - >AdGroupService () - >mutate ({
customerId = > $customer_id ,
operations = >
[ $ad_group_operation1 , $ad_group_operation2 , $ad_group_operation3 ],
partialFailure = > "true"
});
return $ad_groups_response ;
}
# Checks if partial failure error exists in the given mutate ad group response.
sub check_if_partial_failure_error_exists {
my $ad_groups_response = shift ;
if ( $ad_groups_response - >{ partialFailureError }) {
print "Partial failures occurred. Details will be shown below.\n" ;
} else {
print
"All operations completed successfully. No partial failures to show.\n" ;
}
}
# Prints results of the given mutate ad group response. For those that are partial
# failure, prints all their errors with corresponding operation indices. For those
# that succeeded, prints the resource names of created ad groups.
sub print_results {
my $ad_groups_response = shift ;
# Find the failed operations by looping through the results.
while ( my ( $operation_index , $result ) =
each @ { $ad_groups_response - >{ results }})
{
if ( is_partial_failure_result ( $result )) {
my $google_ads_errors = get_google_ads_errors ( $operation_index ,
$ad_groups_response - >{ partialFailureError });
foreach my $google_ads_error ( @$google_ads_errors ) {
printf "Operation %d failed with error: %s\n" , $operation_index ,
$google_ads_error - >{ message };
}
} else {
printf "Operation %d succeeded: ad group with resource name '%s'.\n" ,
$operation_index , $result - >{ resourceName };
}
}
}
# Don't run the example if the file is being included.
if ( abs_path ( $0 ) ne abs_path ( __FILE__ )) {
return 1 ;
}
# Get Google Ads Client, credentials will be read from ~/googleads.properties.
my $api_client = Google::Ads::GoogleAds:: Client - >new ();
# By default examples are set to die on any server returned fault.
$api_client - >set_die_on_faults ( 1 );
# Parameters passed on the command line will override any parameters set in code.
GetOptions ( "customer_id=s" = > \ $customer_id , "campaign_id=i" = > \ $campaign_id );
# Print the help message if the parameters are not initialized in the code nor
# in the command line.
pod2usage ( 2 ) if not check_params ( $customer_id , $campaign_id );
# Call the example.
handle_partial_failure ( $api_client , $customer_id =~ s/-//g r , $campaign_id );
=pod
=head1 NAME
handle_partial_failure
=head1 DESCRIPTION
This example shows how to deal with partial failures. There are several ways of
detecting partial failures. This example highlights the top main detection
options: empty results and error instances.
=head1 SYNOPSIS
handle_partial_failure.pl [options]
-help Show the help message.
-customer_id The Google Ads customer ID.
-campaign_id The campaign ID.
=cut
의견 보내기
달리 명시되지 않는 한 이 페이지의 콘텐츠에는 Creative Commons Attribution 4.0 라이선스 에 따라 라이선스가 부여되며, 코드 샘플에는 Apache 2.0 라이선스 에 따라 라이선스가 부여됩니다. 자세한 내용은 Google Developers 사이트 정책 을 참조하세요. 자바는 Oracle 및/또는 Oracle 계열사의 등록 상표입니다.
최종 업데이트: 2025-12-18(UTC)
의견을 전달하고 싶나요?
[[["이해하기 쉬움","easyToUnderstand","thumb-up"],["문제가 해결됨","solvedMyProblem","thumb-up"],["기타","otherUp","thumb-up"]],[["필요한 정보가 없음","missingTheInformationINeed","thumb-down"],["너무 복잡함/단계 수가 너무 많음","tooComplicatedTooManySteps","thumb-down"],["오래됨","outOfDate","thumb-down"],["번역 문제","translationIssue","thumb-down"],["샘플/코드 문제","samplesCodeIssue","thumb-down"],["기타","otherDown","thumb-down"]],["최종 업데이트: 2025-12-18(UTC)"],[],[]]