Limit Exceptions in CS2009

March 26th, 20092 comments

One flaw with the current design of Commerce Server 2009 is how exceptions are trapped. CS2009 wraps the 2007 object model in a service boundary, logging all exceptions that occur within that boundary and raising a generic FaultException with the following message:

The operation service has encountered an error while processing the request. The error details
have been logged by the service.


This removes the ability to recover from specific exceptions, e.g. ConfiguredLimitExceededException when a user adds too many line items.

A decent workaround for this is to use the other error reporting mechanism that exists in Commerce Server, tunneling via weak properties, e.g. _Basket_Errors. To do this we need two things:

  1. Access to the limits element within the Commerce Server section of web.config
  2. A custom OperationSequenceComponent that will check for limit violations and add a custom status code property to the returned order form.

Accessing the limits element

Commerce Server 2007 uses an internal class, CommerceOrdersConfiguration, to read attributes of the limits element. You can get an instance of this object from the OrderContext using reflection and further use reflection to extract the limit properties needed. See the OrderLimitSettings class in the example code.

Creating a custom OperationSequenceComponent

When new items are added to a basket a call is issued to BasketLineItemsProcessor.CreateRelatedItems. This is part of the CommerceUpdateOperation_Basket operation defined within the channel configuration file. This method receives a collection of line items to create, so we can extend this component to check for limit violations. There’s actually not a lot of code for this:

protected override void CreateRelatedItems(
    List<CommerceCreateRelatedItem> createRelatedItemOperations) {

    var orderForm = CachedOrderGroup.GetDefaultOrderForm();
    if ((orderForm.LineItems.Count + createRelatedItemOperations.Count) >
         Limits.LineItemCountPerOrderFormLimit) {
        orderForm[StatusCodeKey] = LineItemLimitExceeded;
        return;
    }

    base.CreateRelatedItems(createRelatedItemOperations);
}

Note: For this example it’s all or nothing when adding a batch of line items. If adding a new batch will exceed the configured limit, a status code is returned to indicate error preventing the entire batch from being created. Alternatively you could extend BasketLineItemsProcessor.CreateRelatedItem allowing individual line items to be inserted until one violates a limit.

Once the component is complete we need to register it in the CommerceUpdateOperation_Basket operation, within the channel configuration file, by modifying the existing Line Items processor to point to the new class.

You can download an example here.

Posted in CommerceServer

  • TechMate

    Is there an equivalent code to try the same in CS 2007 ?

  • Anonymous

    I might be misunderstanding your question, but in 2007 you can just catch the exception when adding a LineItem to a LineItemCollection.