PO BOX checker script production error

Solved
Dominic_Nadeau
Tourist
12 0 0

Hi,

 

I managed to get a script to work to hide Expedited Shipping for PO Boxes and show Standard Shipping instead (It's the only time we show Standard Shipping).

 

We launched a week ago and since then, I got 8 production errors (with dozens of sales). It's always the same RuntimeError: undefined method 'upcase' for nil


Can anyone help me figure out what's going on? I really appreciate it!

 

Here's the script, the error happens on row 2 where I put the word in bold:

 

#Script begin

#Exclude Expedited option when PO Box is present
shippingaddress1 = Input.cart.shipping_address.address1.upcase.split[0...-1].join ' '
checkpobox = ['PO BOX','POBOX','P.O BOX','PO. BOX','P.O.BOX','P.O. BOX','P.0. BOX','P.OBOX']
puts shippingaddress1
#define hideship based on checkpobox. If so, hide shipping options, otherwise allow all
if checkpobox.include?(shippingaddress1)
hideship = ['Expedited']
else
hideship = ['Standard']
end

#With hideship defined, now we loop through shipping rates to delete those that match
Output.shipping_rates = Input.shipping_rates.delete_if do |shipping_rate|
hideship.any? { |hideship| shipping_rate.name.include?(hideship) }
end

#Script end

Accepted Solution (1)
SBD_
Shopify Staff
Shopify Staff
1098 146 229

This is an accepted solution.

Hey @Dominic_Nadeau 

 

Try wrapping the code instead:

 

unless Input.cart.shipping_address.address1.nil?
  ...your code
end

Scott | Developer Support @ Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit Shopify.dev or the Shopify Web Design and Development Blog

View solution in original post

Replies 16 (16)
SBD_
Shopify Staff
Shopify Staff
1098 146 229

Hey @Dominic_Nadeau

 

This will occur if address1 is blank.

 

Wrap your login in "if there's a shipping address1...", or use a Safe Navigation Operator.

Scott | Developer Support @ Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit Shopify.dev or the Shopify Web Design and Development Blog

Dominic_Nadeau
Tourist
12 0 0

Ok, so what I understand is that it does not really affect the customer's experience since the error only triggers when a required field is blank (it can't be blank anyway to proceed to shipping). So, that's great, I'm worrying less.

 

Could you please elaborate on how to implement the IF within my code? I am not really knowledgeable on Ruby.

 

Thank you

SBD_
Shopify Staff
Shopify Staff
1098 146 229

Are you able to share the store URL? The scripts editor should shed some light on how these are coming through.

Scott | Developer Support @ Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit Shopify.dev or the Shopify Web Design and Development Blog

Dominic_Nadeau
Tourist
12 0 0
Yes, the store URL is ironbullstrength.com
SBD_
Shopify Staff
Shopify Staff
1098 146 229

Thanks @Dominic_Nadeau 

 

it can't be blank anyway to proceed to shipping

I thought the same thing, so I just dug a little deeper. It turns out Google Pay can trigger Shipping Scripts without an address1. The timing seems to line up with the latest error that was generated + order #8643 (which used GPay).

 

To get around this, short-circuit the script:

 

return if cart.shipping_address.address1.nil?

...the rest of your script

 

Scott | Developer Support @ Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit Shopify.dev or the Shopify Web Design and Development Blog

Dominic_Nadeau
Tourist
12 0 0
Hi,

Thank you for your reply.

I tried including this at the beginning of the script.

This generated the following error code on its line:
Undefined method 'cart' for main

What does that mean?


SBD_
Shopify Staff
Shopify Staff
1098 146 229

Apologies, typo:

 

return if Input.cart.shipping_address.address1.nil?

Be sure to test this before publishing. 

Scott | Developer Support @ Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit Shopify.dev or the Shopify Web Design and Development Blog

Dominic_Nadeau
Tourist
12 0 0

Hi Scotty,

 

Yesterday, I added the line to the script and tested it out without errors before publishing.

 

Today, though, I received 2 new RuntimeError for "unexpected return".

What does that mean?

 

It was followed by orders US#8679 and US#8680 both paid using Shopify Payment.

 

Thank you for you help

SBD_
Shopify Staff
Shopify Staff
1098 146 229

This is an accepted solution.

Hey @Dominic_Nadeau 

 

Try wrapping the code instead:

 

unless Input.cart.shipping_address.address1.nil?
  ...your code
end

Scott | Developer Support @ Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit Shopify.dev or the Shopify Web Design and Development Blog

Dominic_Nadeau
Tourist
12 0 0

Hi again,

 

After applying the fixes mentioned above, I didn't get errors for a while.

 

Unfortunately, I now ran into a new RuntimeError:

undefined method 'map' for nil on line 7

 

Is this something you are familiar with?

 

runtimeerror.png

Thanks

SBD_
Shopify Staff
Shopify Staff
1098 146 229

Hey @Dominic_Nadeau

 

Output.shipping_rates always need to be set. In this case it's only set when address1 has a value. A quick fix would be to replace the last end with:

 

else
  Output.shipping_rates = Input.shipping_rates
end

Be sure to test the update before publishing 🙂

Scott | Developer Support @ Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit Shopify.dev or the Shopify Web Design and Development Blog

Dominic_Nadeau
Tourist
12 0 0

Hi Scotty,

 

It seemed like the script was working fine for a while. We then received a few messages from customers trying to order from Hawaii that would not see any rate returned.

Deactivating the script enabled the "Standard Shipping" rate to be shown. Would you have any idea why this would happen and how to fix it?

 

 Here's the complete script:

#Exclude Expedited option when PO Box is present
unless Input.cart.shipping_address.address1.nil?
shippingaddress1 = Input.cart.shipping_address.address1.upcase.split[0...-1].join ' '
checkpobox = ['PO BOX','POBOX','P.O BOX','PO. BOX','P.O.BOX','P.O. BOX','P.0. BOX','P.OBOX']
puts shippingaddress1
#define hideship based on checkpobox. If so, hide shipping options, otherwise allow all
if checkpobox.include?(shippingaddress1)
hideship = ['Expedited']
else
hideship = ['Standard Shipping']
end

#With hideship defined, now we loop through shipping rates to delete those that match
Output.shipping_rates = Input.shipping_rates.delete_if do |shipping_rate|
hideship.any? { |hideship| shipping_rate.name.include?(hideship) }
end

else
Output.shipping_rates = Input.shipping_rates
end

SBD_
Shopify Staff
Shopify Staff
1098 146 229

Hey @Dominic_Nadeau 

Scripts can't see shipping profiles but you could examine the shipping address instead. Maybe something like:

unless Input.cart.shipping_address.address1.nil? or Input.cart.shipping_address.province_code == 'HI'
  ...

 
Be sure to test this as a preview before publishing.

Scott | Developer Support @ Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit Shopify.dev or the Shopify Web Design and Development Blog

Dominic_Nadeau
Tourist
12 0 0

Hey @SBD_

Thanks for your answer.

 

If I understand correctly, the complete code should look like this:

#Exclude Expedited option when PO Box is present
unless Input.cart.shipping_address.address1.nil?
shippingaddress1 = Input.cart.shipping_address.address1.upcase.split[0...-1].join ' '
checkpobox = ['PO BOX','POBOX','P.O BOX','PO. BOX','P.O.BOX','P.O. BOX','P.0. BOX','P.OBOX']
puts shippingaddress1
#define hideship based on checkpobox. If so, hide shipping options, otherwise allow all
if checkpobox.include?(shippingaddress1)
hideship = ['Expedited']
else
unless Input.cart.shipping_address.province_code == 'HI'
hideship = ['Standard Shipping']
end
end
#With hideship defined, now we loop through shipping rates to delete those that match
Output.shipping_rates = Input.shipping_rates.delete_if do |shipping_rate|
hideship.any? { |hideship| shipping_rate.name.include?(hideship) }
end

else
Output.shipping_rates = Input.shipping_rates
end

 

If I want to add province codes, should it look like 'HI, AK, AE' ?

I am also getting an "undefined method 'address1' for nil  error on line 2 since before I added the new code...

 

I am going to test things out, but I feel like the error will get in the way. 

Dominic_Nadeau
Tourist
12 0 0

Update*

Hey @SBD_,

I managed to get the script working again (Standard shipping is hidden except for Hawaii, ALaska and the Armed Forces).

One functionality I lost in the meantime is to hide Expedited shipping and show Standard Shipping when any version of the word PO Box is in the address1 field.

 

Could you please help me figure out what the issue could be? Complete code:

 

#Exclude Expedited option when PO Box is present
unless Input.cart.shipping_address.address1.nil? or Input.cart.shipping_address.province_code == 'HI' or Input.cart.shipping_address.province_code == 'AK' or Input.cart.shipping_address.province_code == 'AA' or Input.cart.shipping_address.province_code == 'AE' or Input.cart.shipping_address.province_code == 'AP'
shippingaddress1 = Input.cart.shipping_address.address1.upcase.split[0...-1].join ' '
checkpobox = ['PO BOX','POBOX','P.O BOX','PO. BOX','P.O.BOX','P.O. BOX','P.0. BOX','P.OBOX']
puts shippingaddress1
#define hideship based on checkpobox. If so, hide shipping options, otherwise allow all
if checkpobox.include?(shippingaddress1)
hideship = ['Expedited']
else

hideship = ['Standard Shipping']

end

#With hideship defined, now we loop through shipping rates to delete those that match
Output.shipping_rates = Input.shipping_rates.delete_if do |shipping_rate|
hideship.any? { |hideship| shipping_rate.name.include?(hideship) }

end
else
Output.shipping_rates = Input.shipping_rates
end

 

Thanks for your help!

Dominic_Nadeau
Tourist
12 0 0

Hi Scotty,

 

One thing I forgot to mention: Hawaii is in a different shipping profile which does not return Expedited Shipping rates. I think that since there is no PO Box in the address, it applies the "Else" condition, hiding the Standard shipping rate. How can I only activate the script for one shipping profile?

 

Thank you