WWW-SFDC
view release on metacpan or search on metacpan
lib/WWW/SFDC.pm view on Meta::CPAN
# static C<use> statements.
for my $module (qw'
Apex Constants Metadata Partner Tooling
'){
has $module,
is => 'ro',
lazy => 1,
default => sub {
my $self = shift;
require "WWW/SFDC/$module.pm"; ## no critic
"WWW::SFDC::$module"->new(session => $self);
};
}
}
method _login {
INFO "Logging in...\t";
my $request = SOAP::Lite
->proxy(
$self->url()."/services/Soap/u/".$self->apiVersion()
)
->readable(1)
->ns("urn:partner.soap.sforce.com","urn")
->call(
'login',
SOAP::Data->name("username")->value($self->username),
SOAP::Data->name("password")->value($self->password)
);
TRACE "Request: " . Dumper $request;
WWW::SFDC::CallException->throw(
message => "Login failed: " . $request->faultstring,
request => $request
) if $request->fault;
return $request->result();
}
method _doCall ($attempts, $URL, $NS, $method, @params) {
# This is the utility method behind call(). It orchestrates the actual
# SOAP::Lite call with the correct parameters and detects connection vs
# SOAP errors.
INFO "Starting $method request";
if (
my $result = eval {
# SOAP::Lite dies when there's a connection error; if there's an API
# error it lives but $result->fault is set. This allows us to detect
# network errors and retry.
SOAP::Lite
->proxy($URL)
->readable(1)
->default_ns($NS)
->call(
$method,
@params,
SOAP::Header->name("SessionHeader" => {
"sessionId" => $self->loginResult->{"sessionId"}
})->uri($NS)
);
}
) {
return $result;
} elsif ($attempts) {
# Looping by recursion makes it easier to write this bit.
INFO "$method failed: $@";
INFO "Retrying ($attempts attempts remaining)";
return $self->_doCall($attempts-1, $URL, $NS, $method, @params);
} else {
WWW::SFDC::CallException->throw(
message => "$method failed: " . $@
);
}
}
method call (@_) {
my $result;
until (
# CallResult is falsy when the call failed
$result = $self->_doCall($self->attempts, @_)
) {
TRACE "Operation request " => Dumper $result;
if ($result->faultstring =~ /INVALID_SESSION_ID/) {
$self->loginResult($self->_login());
} else {
WWW::SFDC::CallException->throw(
message => "$_[2] failed: " . $result->faultstring,
request => $result
);
}
}
return WWW::SFDC::CallResult->new(request => $result);
};
method isSandbox {
return $self->loginResult->{sandbox} eq "true";
}
1;
package WWW::SFDC::CallException;
# CallException allows sensible handling of API errors;
# L<WWW::SFDC::Role::Exception> provides overloaded stringification so that
# when you C<die $exception;> there's a sensible error message, but you can
# still examine the request and response in a consumer library.
use strict;
use warnings;
use Moo;
with 'WWW::SFDC::Role::Exception';
( run in 0.643 second using v1.01-cache-2.11-cpan-39bf76dae61 )