pullingshots / Shipment

Perl interface into various shipping web service API's - FedEx, UPS, Purolator, Temando, Canada Post
https://metacpan.org/pod/Shipment
19 stars 19 forks source link

UPS Errors not being handled correctly #43

Closed TraceyC77 closed 2 years ago

TraceyC77 commented 2 years ago

I'm getting an error from the UPS APi using Shipment::UPS. The calls were working last week, and don't work today. While the error being returned from UPS is probably not a result of this module's code, the way the error is being handled by these modules is problematic. I'm happy to answer questions or provide other information to help troubleshoot the problem.

Printing the dump of the shipment data structure, the only data related to the error is 'An exception has been raised as a result of client data.' This doesn't include the actual error code (which would be referenced in the UPS docs).

Here is a snippet of the dump with some surrounding data:

  'bill_type_map' => {
                       'recipient' => 'BillReceiver',
                       'third_party' => 'BillThirdParty',
                       'sender' => 'BillShipper'
                     },
  'printer_type' => 'thermal',
  'notice' => '',
  'error' => 'An exception has been raised as a result of client data.',
  'package_type_map' => {
                          'custom' => '02',
                          'pack' => '04',
                          'box' => '21',
                          '10kg_box' => '25',
                          'large_express_box' => '2c',
                          'envelope' => '01',
                          'small_express_box' => '2a',
                          'pallet' => '30',
                          'medium_express_box' => '2b',
                          '25kg_box' => '24',
                          'tube' => '03'
                        },
  'pickup_type' => 'pickup',
  'signature_type' => 'default',

After passing debug=1 into the test code, I get errors indicating the error data is not being handled correctly:

ok 19 - shipment has 1 package
Can't locate object method "get_RatedShipment" via package "SOAP::WSDL::SOAP::Typelib::Fault11". 
Valid methods are: get_faultstring, set_faultstring, get_faultcode, set_faultcode, get_faultactor, set_faultactor, get_detail, set_detail
 at /loader/0x4016780/SOAP/WSDL/XSD/Typelib/ComplexType.pm line 72.
        SOAP::WSDL::XSD::Typelib::ComplexType::AUTOMETHOD(SOAP::WSDL::SOAP::Typelib::Fault11=SCALAR(0x6cef4a0), 114226336) called at /usr/local/perl-5.30.0/lib/site_perl/5.30.0/Class/Std.pm line 545
        Class::Std::AUTOLOAD(SOAP::WSDL::SOAP::Typelib::Fault11=SCALAR(0x6cef4a0)) called at /usr/local/perl-5.30.0/lib/site_perl/5.30.0/Shipment/UPS.pm line 380
        Shipment::UPS::try {...} () called at /usr/local/perl-5.30.0/lib/site_perl/5.30.0/Try/Tiny.pm line 102
        eval {...} called at /usr/local/perl-5.30.0/lib/site_perl/5.30.0/Try/Tiny.pm line 93
        Try::Tiny::try(CODE(0x5e19be0), Try::Tiny::Catch=REF(0x57cc498)) called at /usr/local/perl-5.30.0/lib/site_perl/5.30.0/Shipment/UPS.pm line 424
        Shipment::UPS::_build_services(Shipment::UPS=HASH(0x5b3eab0)) called at (eval 659) line 22
        Shipment::Base::services(Shipment::UPS=HASH(0x5b3eab0)) called at t/integration/ups.t line 102
Can't call method "get_PrimaryErrorCode" on unblessed reference at /usr/local/perl-5.30.0/lib/site_perl/5.30.0/Shipment/UPS.pm line 417.
Error: An exception has been raised as a result of client data. at /usr/local/perl-5.30.0/lib/site_perl/5.30.0/Shipment/UPS.pm line 421.
TraceyC77 commented 2 years ago

We had been using UPS.pm 3.07 and just updated the module, but we get the same error. $Shipment::UPS::VERSION = '3.08';

Here's the relevant part of the stack trace after the update:

20220705/18:03:23 Can't locate object method "get_RatedShipment" via package "SOAP::WSDL::SOAP::Typelib::Fault11". 
Valid methods are: get_detail, set_detail, get_faultactor, set_faultactor, get_faultstring, set_faultstring, get_faultcode, set_faultcode
 at /loader/0xb9a8468/SOAP/WSDL/XSD/Typelib/ComplexType.pm line 72.
        SOAP::WSDL::XSD::Typelib::ComplexType::AUTOMETHOD(SOAP::WSDL::SOAP::Typelib::Fault11=SCALAR(0xe7a3180), 242889088) called at /usr/local/perl-5.30.0/lib/site_perl/5.30.0/Class/Std.pm line 545
        Class::Std::AUTOLOAD(SOAP::WSDL::SOAP::Typelib::Fault11=SCALAR(0xe7a3180)) called at /usr/local/perl-5.30.0/lib/site_perl/5.30.0/Shipment/UPS.pm line 383
        Shipment::UPS::try {...} () called at /usr/local/perl-5.30.0/lib/site_perl/5.30.0/Try/Tiny.pm line 102
        eval {...} called at /usr/local/perl-5.30.0/lib/site_perl/5.30.0/Try/Tiny.pm line 93
        Try::Tiny::try(CODE(0xe138cb0), Try::Tiny::Catch=REF(0xdd2bc48)) called at /usr/local/perl-5.30.0/lib/site_perl/5.30.0/Shipment/UPS.pm line 445
        Shipment::UPS::_build_services(Shipment::UPS=HASH(0xc104338)) called at (eval 1921) line 22
        Shipment::Base::services(Shipment::UPS=HASH(0xc104338)) called at /usr/local/perl-5.30.0/lib/site_perl/5.30.0/Shipment/UPS.pm line 505
        Shipment::UPS::try {...} () called at /usr/local/perl-5.30.0/lib/site_perl/5.30.0/Try/Tiny.pm line 102
        eval {...} called at /usr/local/perl-5.30.0/lib/site_perl/5.30.0/Try/Tiny.pm line 93

        Try::Tiny::try(CODE(0xdcd3250), Try::Tiny::Catch=REF(0xdcf57f0)) called at /usr/local/perl-5.30.0/lib/site_perl/5.30.0/Shipment/UPS.pm line 512
        ...

20220705/18:10:47 Can't call method "get_PrimaryErrorCode" on unblessed reference at lib/Shipment/UPS.pm line 432.
20220705/18:10:47 Error: An exception has been raised as a result of client data. at lib/Shipment/UPS.pm line 442.
20220705/18:10:47 Can't call method "id" on an undefined value at lib/Shipment/UPS.pm line 505.
20220705/18:10:47 service (ground) not available at lib/Shipment/UPS.pm line 509.
20220705/18:10:47 Can't call method "id" on an undefined value at lib/Shipment/UPS.pm line 694.
20220705/18:10:47 service (ground) not available at lib/Shipment/UPS.pm line 698.

Looking around, the code around line 383 (the foreach loop) assumes that $response contains the shipment object, but in this case it's returned data from SOAP::WSDL::SOAP::Typelib::Fault11. It seems there needs to be something that checks what's in $response before looping over it, and bubble up get_detail, get_faultstring and get_faultcode if those are defined.

pullingshots commented 2 years ago

Thanks for the report! UPS made a change to their API recently that started rejecting service/rating requests with the signature type set to 'required' which is currently the default in Shipment::UPS. This is documented in issue #44 and a fix will be released shortly to correct the default, but you can manually set signature_type to 'not_required' to get around it immediately. I will leave this issue open as well since you are right that the errors returned for this issue are not being handled correctly by the module.

pullingshots commented 2 years ago

@TraceyC77 could you set debug=2 and post the output? It should spit out the request and response raw xml.

I received a different error than you did - 'The requested accessory option is unavailable between the selected locations.' - so I would like to see what the difference is in the response you got.

pullingshots commented 2 years ago

@TraceyC77 could you set debug=2 and post the output? It should spit out the request and response raw xml.

I received a different error than you did - 'The requested accessory option is unavailable between the selected locations.' - so I would like to see what the difference is in the response you got.

Don't bother with this, I was able to duplicate the response you got.

TraceyC77 commented 2 years ago

Thanks so much for the quick response and quick fix. After deploying 3.09 I'm no longer seeing issues.