Getting SOAP faults while using Google's sample custom report script

61 views
Skip to first unread message

Bill

unread,
Feb 22, 2005, 7:15:14 PM2/22/05
to adwor...@googlegroups.com
Has anyone else had issues getting a custom report using Perl? I've
been grabbing generic keyword reports for a while now with no troubles,
but we have a need to generate a custom report. Trouble is, I can't
get customReportJob to give me back anything -- even using Google's
sample Perl script (which is itself horribly broken).

First off, here's my exact error:

Use of uninitialized value in concatenation (.) or string at
./customrpttest.pl line 76.
Use of uninitialized value in concatenation (.) or string at
./customrpttest.pl line 76.
SOAP Fault: org.xml.sax.SAXException: No deserializer defined for array
type {http://www.w3.org/1999/XMLSchema}ur-type for input "" (Error Code
) at ./customrpttest.pl line 76.

(Those concat errors are from the sample script's faulthandler()
subroutine, BTW.)

Here's the script. It's essentially Google's sample custom report
script (at
http://www.google.com/apis/adwords/samples/perl/customreport.pl.txt)
with some tweaks. (I added a few semicolons, made the occasional
variable names match, added 'use SOAP::Lite' and 'use strict' pragmas.
Basically, it'll at least compile now.)


#!/usr/bin/perl -w
#
# Copyright 2004 Google

# Sample AdWords API client code for sending CustomReportJobs to
ReportService.
# Note that this code requires SOAP::Lite 0.65 or better to work
correctly.

use SOAP::Lite;
use strict;


# Uncomment and fill this in with your login information.
#
my $url =
"http://adwords.google.com/api/adwords/v2/ReportService?WSDL";
my $email = 'my_email';
my $password = 'my_passwd';
my $useragent = 'my_useragent';
my $token = 'my_token';
my $namespace = "https://adwords.google.com/api/adwords/v2";

# Set up the connection to the server.
my $service = SOAP::Lite->service($url);

# Disable autotyping.
$service->autotype(0);

# Uncomment this line to display the XML request/response.
$service->on_debug( sub { print @_ } );

# Register a fault handler.
$service->on_fault(\&faulthandler);

my @headers =

(SOAP::Header->name("email")->value($email)->uri($namespace)->prefix("impl"),

SOAP::Header->name("password")->value($password)->uri($namespace)->prefix("impl"),

SOAP::Header->name("useragent")->value($useragent)->uri($namespace)->prefix("impl"),

SOAP::Header->name("token")->value($token)->uri($namespace)->prefix("impl"));

my $report = {
'name' => 'test',
'aggregationType' => 'Summary',
'startDate' => '2005-02-15T00:00:00',
'endDate' => '2005-02-15T00:00:00',
'campaigns' => [ my_campaign ],
'customOptions' =>
["AveragePosition","Clicks","Cpc","Impressions"],
};
my $req = SOAP::Data->name("CustomReportJob", $report);
$req->attr( {
'xsi:type' => 'impl:customReportJob',
'xmlns:impl' => $namespace
} );

my $jobId = $service->scheduleReportJob($req, @headers);

print "Job ID: $jobId\n";

# Wait for the report to finish
my $status;
while ("Completed" ne ($status = $service->getReportJobStatus($jobId,
@headers))) {
print "Report status is $status\n";
sleep(10);
}

# Download the report
my $report_url = $service->getReportDownloadUrl($jobId, @headers);
my $rpt_data = get($report_url);

print $rpt_data if $rpt_data;

# --------------------
sub faulthandler {
my ($soap, $res) = @_;
die("SOAP Fault: " . $res->faultstring . " for input \"" .
$res->faultdetail->{"trigger"} .
"\" (Error Code " . $res->faultdetail->{"code"} . ")");
}

##
## End


Oh yeah, I also added a part that does the actual download. But that's
basically the sample script in its entirety.

I've looked through these groups all day, and have been playing with
headers and such to no avail. I've tried version 0.60a (the latest
stable version) of SOAP::Lite.pm, as well as version 0.65_3 (which the
sample script claims to require). The errors above are from 0.60a. I
can't even make a connection using v0.65_3 of the module (for any kind
of report). I'm using Perl 5.8.5 if it matters.

Here's the request XML trace:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/1999/XMLSchema"

SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">

<SOAP-ENV:Header>
<impl:email
xmlns:impl="https://adwords.google.com/api/adwords/v2">my_email</impl:email>
<impl:password
xmlns:impl="https://adwords.google.com/api/adwords/v2">my_passwd</impl:password>
<impl:useragent
xmlns:impl="https://adwords.google.com/api/adwords/v2">my_useragent</impl:useragent>
<impl:token
xmlns:impl="https://adwords.google.com/api/adwords/v2">my_token</impl:token>
</SOAP-ENV:Header>

<SOAP-ENV:Body>
<scheduleReportJob xmlns="">
<customReportJob
xmlns:impl="https://adwords.google.com/api/adwords/v2"
xsi:type="impl:CustomReportJob">
<aggregationType>Summary</aggregationType>
<endDate>2005-02-15T00:00:00</endDate>
<campaigns SOAP-ENC:arrayType="xsd:ur-type[1]">
<item>my_capmaign_id</item>
</campaigns>
<name>test</name>
<customOptions SOAP-ENC:arrayType="xsd:ur-type[4]">
<item>AveragePosition</item>
<item>Clicks</item>
<item>Cpc</item>
<item>Impressions</item>
</customOptions>
<startDate>2005-02-15T00:00:00</startDate>
</customReportJob>
</scheduleReportJob>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Here's the response:

<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<soapenv:Header>
<response_time
soapenv:actor="http://schemas.xmlsoap.org/soap/actor/next"
soapenv:mustUnderstand="0" xmlns="">36</response_time>
</soapenv:Header>

<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Server.userException</faultcode>
<faultstring>org.xml.sax.SAXException: No deserializer defined
for array type {http://www.w3.org/1999/XMLSchema}ur-type</faultstring>
<detail>
<ns1:stackTrace
xmlns:ns1="http://xml.apache.org/axis/">org.xml.sax.SAXException: No
deserializer defined for array type
{http://www.w3.org/1999/XMLSchema}ur-type
at
org.apache.axis.encoding.ser.ArrayDeserializer.onStartElement(ArrayDeserializer.java:267)
at
org.apache.axis.encoding.DeserializerImpl.startElement(DeserializerImpl.java:399)
at
org.apache.axis.encoding.DeserializationContext.startElement(DeserializationContext.java:1038)
at
org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:159)
at
org.apache.axis.message.MessageElement.publishToHandler(MessageElement.java:1138)
at
org.apache.axis.message.RPCElement.deserialize(RPCElement.java:199)
at
org.apache.axis.message.RPCElement.getParams(RPCElement.java:342)
at
org.apache.axis.providers.java.RPCProvider.processMessage(RPCProvider.java:146)
at
org.apache.axis.providers.java.JavaProvider.invoke(JavaProvider.java:319)
at
org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
at
org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
at
org.apache.axis.handlers.soap.SOAPService.invoke(SOAPService.java:450)
at
org.apache.axis.server.AxisServer.invoke(AxisServer.java:285)
at
org.apache.axis.transport.http.AxisServlet.doPost(AxisServlet.java:637)
at
javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at
org.apache.axis.transport.http.AxisServletBase.service(AxisServletBase.java:301)
at
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at
com.google.gse.HttpConnection.runServlet(HttpConnection.java:242)
at
com.google.gse.HttpConnection.run(HttpConnection.java:194)
at
com.google.gse.DispatchQueue$WorkerThread.run(DispatchQueue.java:219)
</ns1:stackTrace>
</detail>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>

Sorry for the long post, but I wanted to be as complete as possible.

Has anyone gotten (at least) the sample custom report Perl script to
work? If so, can you paste in your code? I'm sure there's something
small I need to tweak, but I'll be darned if I can find it.

Thanks in advance...

Bartosz Jakubski

unread,
Feb 23, 2005, 6:21:13 AM2/23/05
to Bill, adwor...@googlegroups.com
On Tue, 22 Feb 2005 16:15:14 -0800, Bill <wrh...@urchin.com> wrote:
>
> Has anyone else had issues getting a custom report using Perl? I've
> been grabbing generic keyword reports for a while now with no troubles,
> but we have a need to generate a custom report. Trouble is, I can't
> get customReportJob to give me back anything -- even using Google's
> sample Perl script (which is itself horribly broken).

Hello.
Following modification were necessary to run your script correctly
(using SOAP::Lite 0.60):

> my $report = {
> 'name' => 'test',
> 'aggregationType' => 'Summary',
> 'startDate' => '2005-02-15T00:00:00',
> 'endDate' => '2005-02-15T00:00:00',
> 'campaigns' => [ my_campaign ],
> 'customOptions' =>
> ["AveragePosition","Clicks","Cpc","Impressions"],
> };

my $report = {
'name' => 'test',
'aggregationType' => 'Summary',
'startDate' => '2005-02-15T00:00:00',
'endDate' => '2005-02-15T00:00:00',
'campaigns' => SOAP::Data->name(campaigns => qw/my_campaign/),
'customOptions' => SOAP::Data->name(customOptions =>
qw/AveragePosition Clicks Cpc Impressions/),

> my $req = SOAP::Data->name("CustomReportJob", $report);
> $req->attr( {
> 'xsi:type' => 'impl:customReportJob',
> 'xmlns:impl' => $namespace
> } );

You have mangled case in the 'customReportJob' here twice. Google
sample script has it right. It has to be:

my $req = SOAP::Data->name("customReportJob", $report);
$req->attr( {
'xsi:type' => 'impl:CustomReportJob',
'xmlns:impl' => $namespace
} );


Regards,
--
Bartosz Jakubski
Hurra Communications Sp. z o.o.

Bill

unread,
Feb 23, 2005, 3:14:10 PM2/23/05
to adwor...@googlegroups.com
Thanks, Bartosz. That seems to work like a champ (my unintentional
case mangling notwithstanding).

japh

unread,
Mar 13, 2005, 5:31:51 AM3/13/05
to adwor...@googlegroups.com
I was having the same problem with SOAP::Lite and this fixed it. Thanks
so much!!

Reply all
Reply to author
Forward
0 new messages