Compatibility Mode Considerations

Your site uses one of the following compatibility modes: 10.4, 10.6, 13.6, 15.5, 16.1, 16.2, 17.7 or 18.2.

To upgrade to the latest compatibility mode, you will need to understand what changed between modes, so that you can make the corresponding changes to your code. This page provides you with a description of those changes, as documented in the release notes.

The dw.system.System.getCompatibilityMode() method returns the compatibility mode of the custom code version that is currently active. The compatibility mode is returned as a number, for example, compatibility mode 15.5 is returned as 1505.

18.10

The dw.util.StringUtils#formatNumber(number,format,locale) API method now respects the regional settings of the locale for grouping and decimal characters.

Prior to Compatibility Mode 18.10, this method ignored the defined regional settings and used the format setting from Java for the specified locale.

18.2

Exceptions from Javascript functions called by script API classes were wrapped as a SystemError. This led to issues if the exception was an APIException, because the additional properties were not accessible.

A method where this occurred is dw.util.Transaction.wrap():

try {
 dw.util.Transaction.wrap(function () {
   throw new Error("my error");
   });
 } catch (e)
 {
 return {message: e.message, name: e.name}; 
 }

Prior to Compatibility Mode 18.2, this example returned the unexpected result:

message: com.demandware.core.script.capi.ScriptingException: Error: test error (...) name: SystemError.

With 18.2 Compatibility Mode, the original exception object remains intact, which means the example returns the following message:

test error name: Error

17.7

APP-49849: Changed Argument Handling of ISML.RenderTemplate

The behavior of the dw.template.ISML.renderTemplate() method has changed slightly. The template execution is now scoped. All variables passed to the template are only placed in the dictionary temporarily. After the template finishes, the original pipeline dictionary is recovered. Previously, arguments passed into the template were placed in the global pipeline dictionary. This lead to naming conflicts and changed values in the dictionary after the template returned.

Important: Because this is a breaking change, a new API compatibility mode was added. The new behavior is only activate if API mode is set to 17.7 or later.

16.2

With Compatibility Mode 16.2 it, you can encrypt and decrypt a message with a salt of ‘0’, using the Cipher class in the Salesforce B2C Commerce API. When using a previous compatibility mode, a system-defined salt was used if the developer passed a salt that consisted solely of bytes with value 0x00 or other characters that are represented by ASCII codes less than or equal to 0x20.

Compatibility Mode 16.1 used the following salt values:

If you need to reproduce the behavior of compatibility modes before Release 16.2 on an instance that has 16.2 enabled, use these salts as the salt parameters to encrypt or decrypt.

16.1

APP-33920: ECMAScript 5 compliant behavior of global function parseInt(String) in code compatibility version 16.1

Starting with B2C Commerce Script API (code compatibility) version 16.1, the parseInt(String) function is ECMAScript 5 compliant. In older versions, the function was only compliant with ECMAScript 3. The difference is that with ECMAScript 5, octal number support was dropped. Numbers starting with leading zeros are now parsed to radix 10 instead of radix 8, as previously. If the dynamic radix determination isn't needed explicitly, the use of parseInt(String, Number) is still recommended.

APP-34144: Map.Values() Returns a View to the Map in Code Compatibility Version 16.1

Starting with B2C Commerce Script API (code compatibility) version 16.1, the Map.values() method now returns a view to a map the same way the Map.keySet() and Map.entrySet() methods did in earlier versions. Previously, the Map.values() method returned an independent collection where modification did not change the map.

15.5

APP-32403: SiteGenesis Release 15.3 and 15.4 Developers Must Modify Their Code If Using the Release 15.5 B2C Commerce Script API

A recent change in the way the 15.5 B2C Commerce Script API handles global variables means that customers who have adopted SiteGenesis Releases 15.3 or 15.4 must explicitly declare the paths of global functions such as dw.system.Logger and dw.web.URLUtils.

Who Does This Affect?

This only affects customers using SiteGenesis Releases 15.3 and 15.4, and who have set the B2C Commerce Script API Compatibility Mode to 15.5. This doesn't affect customers using B2C Commerce Script API Version 13.6 or using SiteGenesis 15.2 or earlier or SiteGenesis 15.5 or later.

How Does the Problem Appear?

If you are using SiteGenesis Release 15.3 or 15.4 and you are using B2C Commerce Script API 15.5, you will not be able to access the Cart page in SiteGenesis. You will get an error in your log file as follows:

org.mozilla.javascript.EcmaError: ReferenceError:
 "Logger" isn't defined.
 (app_storefront_core/cartridge/scripts/cart/calculate.js#271)
 in line 271

What Should I Do If This Happens to Me?

  1. If possible, merge SiteGenesis Release 15.5 into your code, or
  2. Simply use the SiteGenesis 15.5 version of calculate.js., or
  3. In calculate.js, replace all calls to Logger() to the fully qualified version, as follows: dw.system.Logger().
  4. Only if you have no opportunity to fix the code to comply with the updated JavaScript standard set the compatibility mode to 13.6.
Note: This as a temporary fix until you can make the required code changes.

APP-23919: Global Scope of Caller Not Accessible by Called Modules with Compatibility Version 15.5

The require() script now works properly within pipelines (Assign Node). Previously, global variables were shared between modules, which limited isolation and reusability. Global variables defined in a module script did not work, while they worked properly when requiring the module in another script.

This is an example:

TopLevelScript.ds


importPackage( dw.system );
 var globalVariable = PIPELET_ERROR;
 function execute( args : PipelineDictionary ) :
 Number
 {
 return require("myModule");
 }

MyModule.ds

var globalVariable;
 module.exports = globalVariable || PIPELET_NEXT;

With compatibility version 15.5, the PIPELET_NEXT is returned, while compatibility versions prior to this returned a PIPELET_ERROR.

Activate the new behavior by selecting compatibility version 15.5.

Customer impact: Review your code for use of the require() script that relies on the leakage of variables from the caller scope into the module.

APP-30008: Cipher Methods Expect a Base64-Encoded Salt with Compatibility Version 15.5

Starting with API Version 15.5, all dw.crypto.Cipher methods expect the salt argument to be base64-encoded.

Note: Passing undefined as salt is no longer possible, because it was previously used for some algorithms. With the new API version, you will encounter an EncryptionException with the message base64 decoding of salt failed.

APP-30138: Module Lifetime Is Entire Request with Compatibility Version 15.5

With code compatibility version 15.5, modules are now loaded and instantiated only once per request. If within script code a require() call requests the module a second time, then the same instance as the first call is returned. This is independent of the location of the require call (pipeline, script files or ISML files).

Previously, the module cache that was held within the implementation of require() was not global per request, but belonged to the JavaScript context. For every new context, a new cache was created. Modules that were resolved in a script were therefore not visible to script sections contained in templates (for example, isscript) because scripts had their scope, and templates had another scope.

APP-30693: Log notification for changed methods in older API Versions

If a method behaviour changes, but the method signature stays the same, and the method is still used with an old B2C Commerce Script API version active (also referred to as Compatibility Mode), B2C Commerce now writes notifications to the API log.

For example, if a fictitious class method apiClass.setMethod(String one) existed in the old B2C Commerce Script API Version 13.6 (which is the last active Compatibility Mode in 15.4) and the behavior changed with the new B2C Commerce Script API (a new Compatibility Mode) in Release 15.5, the usage of apiClass.setMethod in Release 15.5 executed on the old B2C Commerce Script API version 13.6 will log a message such as the following to the API log file:

API Method apiClass.setMethod(String) has been changed in a newer API Version.
Consider updating."

The same invocation on the newer B2C Commerce Script API (Compatibility Mode 15.5 after you activated this new API) will no longer log this type of message.

APP-31925: Strict JSON parsing enforced with code compatibility version 15.5

Starting with B2C Commerce Script API (code compatibility) version 15.5, strict parsing is enforced. Previously, versions of the JSON parsers in B2C Commerce accepted invalid JSON that contained extraneous commas before closing brackets.

APP-32088: ECMAScript compliance issue in B2C Commerce script parser fixed with compatibility version 15.5

When compatibility version 15.5 is selected, an error is thrown when code accesses undeclared properties, which is proper ECMAScript behavior. For compatibility reasons, this behavior is still allowed if you select a compatibility version prior to 15.5.

13.6

APP-18307: SeekableIterator in Pipeline Dictionary

In B2C Commerce script files, you can call API methods that return a dw.util.SeekableIterator instance. A SeekableIterator enables you to iterate over its elements a single time. However, if you put this iterator into the Pipeline Dictionary and your API compatibility mode is prior to 13.6, you can use the iterator multiple times. Depending on the number of elements the iterator represents, this might cause memory usage issues.

As of API compatibility mode 13.6, the elements in the SeekableIterator can only be accessed once. If you are using an API compatibility mode that pre-dates 13.6, there will be entries in the API log indicating that the SeekableIterator is being placed into the Pipeline Dictionary. These log entries should enable you to identify uses of SeekableIterator where moving to 13.6 compatibility mode might cause a change in your Pipeline behavior.

The log entries take the following form:

PipelineDictionary usage violation:
 WARN: dw.util.SeekableIterator put in dictionary.
 KEY: key_name, SCRIPT: script_name

where key_name is the pipeline dictionary key, and script_name is the name of the script that is putting the SeekableIterator into the dictionary.

10.6

APP-46080: SeekableIterator.close() now ensures that the iterator is actually closed

As of Release 17.2, SeekableIterator.close() now ensures that the iterator is actually closed. Previously in some situations, it was possible to read elements from a dw.util.SeekableIterator even after close was explicitly called.

Customer impact: for compatibility modes 10.6 and greater, the iterator should always be empty after a call to close().

APP-15882: API Behavior Change When Accessing SeekableIteratot via the Pipeline Dictionary

Instances of SeekableIterator are returned in the API whenever a method returns mass data. Starting with API version 10.6, these iterators can only be iterated once to avoid possible memory problems for really large iterators. Putting them into the pipeline dictionary and trying to loop them multiple times is no longer possible because this would require buffering the iterated elements internally.

Previously, and for all customers still running API version 10.4 (compatibility mode), SeekableIterator instances stored in the pipeline dictionary could be iterated multiple times (for example, by several loop nodes).

Customer Impact: Check your code for instances of SeekableIterator and adjust as required.

Product Attributes Set At Site Level (No Release Note)

With Compatibility Mode 10.6, the product attributes onlineFlag, searchableFlag, searchPlacement, and searchRank are set at the site level. Previously they were set at global level.

APP-15381: Improved ProductAttributeModel Methods GetValue() and GetDisplayValue()

The getValue() and getDisplayValue() ProductAttributeModel methods now return a MediaFile instance in case of a custom image attribute, or a MarkupText instance in case of a custom Html attribute. Previously, both methods returned the image path or the Html source as a simple String.

Note: Compatibility mode 10.6 must be activated for your code version to take advantage of this functionality.

APP-12148: Inventory levels are now adjusted on order cancellation and order Replacement

For instances configured (via API versioning) to use the B2C Commerce API version 10.6 or later, inventory levels are now adjusted to reflect items from canceled or replaced orders. Previously, when an order was canceled or replaced, no change was made to inventory levels.

Example 1: If an order has 5 units of product X, when the order is canceled, the amount of product X available increases by five units.

Example 2: Assume the following:

If order A is replaced by order B, then the number of units available change: -1 units of X, +2 units of Y, and -5 units of Z

When replacing order A with order B, the inventory levels now reflect that the items in order A are available.

10.4

This is the original behavior. You have this version or greater.

Related Links

Understanding Compatibility Modes