bloxHub

www.infoblox.com/community
4 posts / 0 new
Croak_If_Error Changes API Output

I'm using the NetMRI Perl API (version 2.4) to create some external automation scripts and I think I'm finding that the state of the croak_if_error attribute of NetMRI::API seems to be changing the way the API returns results. Specifically, it is causing calls to the API to not return objects when it should.

Consider this script (based on the sample sync_external.pl included in the docs):

  1. use strict;
  2. use warnings;
  3. use Data::Dumper;
  4. use NetMRI::API;
  5.  
  6. # Connect to the NetMRI.
  7. my $client = new NetMRI::API({
  8. username => "admin",
  9. password => "mypassword",
  10. url => "<a href="http://192.168.1.1",
  11. ">http://192.168.1.1",
  12. </a> api_version => '2.4',
  13. croak_if_error => "1"
  14. });
  15.  
  16. # run the script against the devices specified on the
  17. # command line.
  18. my($job_id) = $client->broker->script->run({
  19. name => 'Ad Hoc Command Batch',
  20. device_ids => \@ARGV,
  21. '$CommandBatch' => 'show version',
  22. })->{JobID};
  23.  
  24. # fetch the Job object
  25. my $job = $client->broker->job->show({ JobID => $job_id })->{job};
  26.  
  27. print Dumper($job);
  28.  
  29. print "Status: ", $job->wait, "\n";

This script runs just fine if croak_if_error is set to 1, but it fails if croak is set to 0. The error posted is:

Can't call method "wait" on an undefined value at jobtest.pl

It looks like this is happening because we expect $job to come back as an object, but it only does so if croak is set to 1.

The API docs say:

By default an exception is thrown using die when an error occurs communicating with the NetMRI appliance. If this is set to true, then you will instead get a NetMRI::API::Response object returned back to you.

I read that as saying - "If you set croak to 1 and send an invalid API call, the script fails with a call to Perl's die function. If you set croak to 0 and send an invalid API call, the call returns an object of type NetMRI::API::Response." I prefer to set croak to 0 because I can then test the Response object and more gracefully handle errors. However, I can't do this because croak seems to be telling the API never to return objects, rather than never to return them on invalid API calls.

Is what I'm seeing here right? Is this "by design" in the API? If so how can I more elegantly handle errors? If not, has it been fixed?

Thanks.

+1
+1
-1
Tags
NetMRI,Debugging,Perl
Re: Croak_If_Error Changes API Output

Your understanding is correct. Your code though shows you accessing the JobID directly from the response object. If it is a NetMRI::API::Response, I believe there is a content method you need to call first. That doesn't explain an undefined object though. For that, try making the call in a scalar context:

my $job_id;
my $r = $client->broker->script->run({name => 'Ad Hoc Command Batch',
device_ids => \@ARGV, '$CommandBatch' => 'show version',});
if ($r->success) {
  $job_id = $r->content->{JobID};
}

Note: no ( ) around $job_id on the left-hand-side. If that give the same problem, then this likely is a defect. However, as a workaround, the preferred method for error handling is to use croak_if_error => 1, and wrap the calls in an eval {};


eval {
  my $job_id = $client->broker->script->run({name => 'Ad Hoc Command Batch',
    device_ids => \@ARGV, '$CommandBatch' => 'show version',})->{JobID};

  # fetch the Job object

  my $job = $client->broker->job->show({ JobID => $job_id })->{job};

};

if ($@) {
  # handle error here
  print $@,"\n";
}

 

John

+1
0
-1
Re: Croak_If_Error Changes API Output

John - thanks for the response on this.

I took your suggested code to make the call in a scalar context and I'm still seeing the same error depending on the state of croak.

use strict;
use warnings;
use Data::Dumper;
use NetMRI::API;

# Connect to the NetMRI.
my $client = new NetMRI::API({
username => "admin",
password => "mypassword",
url => "http://192.168.1.1",
api_version => '2.4',
croak_if_error => "1"
});

my $job_id;
my $r = $client->broker->script->run({
name => 'Ad Hoc Command Batch',
device_ids => \@ARGV,
'$CommandBatch' => 'show version'
});
print Dumper($r);
if ($r->success) {
$job_id = $r->content->{JobID};
}

# fetch the Job object
my $job = $client->broker->job->show({ JobID => $job_id })->{job};

print Dumper($job);

print "Status: ", $job->wait, "\n";

The root cause seems to be that the state of croak. If croak is set to 1, then $r comes back with a value for JobID and nothing else. (That also causes the call to $r->success to fail).

If croak is set to 0, then $r comes back as an object of type NetMRI::API::Response and our call to wait fails as undefined object.

I can wrap my code in eval to get around this, but I do think that this isn't working as intended.

+1
+1
-1
Re: Croak_If_Error Changes API Output

What does the Dumper($r) output look like?

I think the issue is that every API request will now return a response object. So, instead of  

 

# fetch the Job object
my $job = $client->broker->job->show({ JobID => $job_id })->{job};

 

You need to do
 
my $job;
$r = $client->broker->job->show({ JobID => $job_id });
if ($r->success) {
  $job = $r->content->{job};
}

 

 

+1
0
-1