Developer forum

Forum » Development » StackOverflowException in ShippingProvider

StackOverflowException in ShippingProvider

Imar Spaanjaars Dynamicweb Employee
Imar Spaanjaars
Reply

Hi there,

I have a ShippingProvider with the following code:

public override PriceRaw CalculateShippingFee(Order order)
{
  var currencyId = "USD";
  return new PriceRaw(15, new Dynamicweb.eCommerce.International.Currency(currencyId));
}

When I run it, the IIS work process crashes because a StackOverflowException occurs. It seems to crash when getting the current currency from either session or application state (not sure yet).

It works fine when I comment out the method and let the default implementation return null. I also tried getting the current currency like this:

return new PriceRaw(Convert.ToDouble(cost), order.PriceBeforeFees.Currency);

with the same result.

Any idea what's going on?

Imar


Replies

 
Imar Spaanjaars Dynamicweb Employee
Imar Spaanjaars
Reply

Found it. The code I posted was a little too simplistic for demo purposes. In my real code I was calling a custom order extension method. That method accesses properties of the order and loops over the order line (not sure which one it is yet). Apparently, accessing this data somehow causes the ShippingProvider to be called again, causing a recursive loop. I now keep track of the state in HttpContect.Current.Items and only allow the method to calculate once per Http request.

Imar

 
Goncalo Faria
Reply

I am having the same issue. First I had the stackoverflow problem and noticed that I was fetching shipping information during the calculate. Removed that but now it still happens consistely 11 times per call.

Could you explaing to me how do you keep track of the state in httpContext.Current.Items?

 

Thank you

 
Imar Spaanjaars Dynamicweb Employee
Imar Spaanjaars
Reply
This post has been marked as an answer

You can do something like this (untested, written here but it should hopefully get you started, If you can't get it to work let me know).

if (HttpContext.Current.Request.Items["IsHandlingShipping"] != null)
{
  return;
}

HttpContext.Current.Request.Items["IsHandlingShipping"] = true;

// Calculate fees here

The idea here is that you check for the presence of a key in the Items collection. If it doesn't exist, it means the code is executed for the first time so you add a key as a marker and then calculate your fee normally. On subsequent calls on the same http request, the key exists and therefore your method will terminate early and not cause an infinite loop.

Hope this helps,

Imar

Votes for this answer: 1
 
Goncalo Faria
Reply

That worked. Thank you for the help @Imar.

This is what I did. Now only calls once per request! Which is perfect. Well.... Almost.

public override PriceRaw CalculateShippingFee(Order order)
{
    if (Dynamicweb.Context.Current.Items["IsHandlingShipping"] != null && Convert.ToBoolean(Dynamicweb.Context.Current.Items["IsHandlingShipping"])) return null;
    
    HttpContext.Current.Items["IsHandlingShipping"] = true;
    var shippingFee = LiveIntegrationService.Instance.CalculateOrder(order);
    return shippingFee != null ? new PriceRaw((double)shippingFee, Dynamicweb.Ecommerce.Common.Context.Currency) : null;
}

Seems that the CalculateShippingFee is not working as intended. Even trying out with an absurd static number, it still gets the default value from the settings.

 

You must be logged in to post in the forum