Skip to main content
Version: 10

Error handling when working with collection attributes

Level: advanced

Creatio provides a dedicated public API in the @creatio/interface-designer library that lets you bind a Freedom UI component property to a collection of view model attributes directly from the setup area code. Learn more: Working with collection attributes when implementing Freedom UI Designer setup area.

The API provides a public SchemaValidationError hierarchy for predictable error handling. All public schema-editing errors inherit from SchemaValidationError. SchemaValidationError is the base class for all public schema-editing errors. This means you can use it as a catch-all fallback to handle any schema validation failure in a single catch block.

Recommendations for error handling​

The following recommendations help you handle errors predictably and maintain consistent setup area state:

  • Check capability before removal. Call the canRemoveAttribute() or canRemoveDataSource() method before removing to avoid errors when the attribute or data source is still referenced elsewhere.

    Example that checks capability before removal
    /* Check whether the collection attribute can be safely removed. */
    const canRemove = await collectionAttributeEditor.canRemoveAttribute('Code');
    if (canRemove) {
    await collectionAttributeEditor.removeAttribute('Code');
    }

    /* Check whether the data source can be safely removed. */
    const canRemoveDS = await schemaEditor.modelEditor.canRemoveDataSource('CityDS');
    if (canRemoveDS) {
    await schemaEditor.modelEditor.removeDataSource('CityDS');
    }
  • Catch specific validation errors. Use instanceof checks against specific error classes such as DataSourceAlreadyExistsError or UnsupportedDataSourceTypeError to handle each case explicitly.

    Example that catches specific validation errors
    import {
    DataSourceAlreadyExistsError,
    SchemaValidationError,
    UnsupportedDataSourceTypeError,
    } from '@creatio/interface-designer';

    try {
    await schemaEditor.modelEditor.createDataSource('CityDS', {
    type: DataSourceType.EntityDataSource,
    entitySchemaName: 'City',
    });
    } catch (error) {
    if (error instanceof DataSourceAlreadyExistsError) {
    console.error(`Data source '${error.dataSourceName}' already exists.`);
    return;
    }
    if (error instanceof UnsupportedDataSourceTypeError) {
    console.error(`Data source type '${error.dataSourceType}' is not supported.`);
    return;
    }
    if (error instanceof SchemaValidationError) {
    console.error(`Schema validation failed: ${error.message}`);
    return;
    }
    throw error;
    }
  • Keep user-friendly messages in the setup area. Catch low-level schema API errors, map them to human-readable messages, and maintain consistent setup area state.

    The following example keeps user-friendly messages in the setup area.

    Example that keeps user-friendly messages in the setup area
    try {
    await this._bindItemsToDataSource(dataSourceName);
    /* Display a success message to the user. */
    this._setOperationMessage(
    'success',
    `Collection attribute was bound to data source '${dataSourceName}'.`
    );
    } catch (error) {
    /* Display a user-friendly error message. */
    const message = error instanceof Error ? error.message : 'Unknown error';
    this._setOperationMessage('error', `Error binding to data source: ${message}`);
    }
  • Use instanceof SchemaValidationError as a fallback. SchemaValidationError overrides Symbol.hasInstance, so instanceof checks work reliably across bundle boundaries, including remote modules and Module Federation scenarios where the same library may be loaded from different bundles.

    try {
    await schemaEditor.viewModelEditor.createAttribute('Items', {
    isCollection: true,
    bindToModel: { dataSourceName: 'CityDS' },
    });
    } catch (error) {
    if (error instanceof SchemaValidationError) {
    console.error('Schema validation error:', error.message);
    }
    }

Common errors​

The following table lists common errors and their solutions when working with collection attributes.

Error

Solution

Attribute with the target name already exists but is not a collection.

  1. Check whether the attribute name is free.
  2. Create a new collection attribute if the name is free. If the name is taken, verify it is safe to remove using the canRemoveAttribute() method, then remove and recreate the attribute.

Nested attribute already exists but has the wrong binding.

  1. Check the existing binding.
  2. Reuse it if it is already correct. If it is incorrect, verify it is safe to remove using the canRemoveAttribute() method, then remove and recreate it.

Collection attribute is removed but the data source is still used elsewhere.

  1. Remove the collection binding and the collection attribute.
  2. Call the canRemoveDataSource() method before deleting the data source.
  3. If the data source cannot be removed, keep it and show an informational message instead of treating it as an error.

Data source already exists but points to another object schema.

  1. Use entitySchemaName to read the actual object schema name.
  2. Report the conflict clearly to the user.
  3. Ask the user to enter a different object schema name or remove the conflicting data source.
Example that handles the case when the data source already exists but points to another object schema
const editor = await schemaEditor.modelEditor.getDataSourceEditor(dataSourceName);

if (editor?.dataSourceType === DataSourceType.EntityDataSource
&& editor.entitySchemaName !== expectedEntityName) {
/* Data source 'CityDS' is already bound to 'Account', not 'City'. */
}

Error handling when working with data sources​

The following error classes may be thrown when creating, reading, or removing data sources and their attributes.

Error class

Trigger

Solution

DataSourceAlreadyExistsError

Creating a data source with an existing name.

Reuse it if compatible or show a conflict message.

DataSourceNotFoundError

Calling the removeDataSource() method for a data source that does not exist.

Validate the data source name before operating on it.

DataSourceAttributeAlreadyExistsError

Creating an existing data source attribute.

Reuse the existing attribute or verify its configuration before proceeding.

BoundDataSourceRemovalError

Removing a data source that is still used elsewhere.

Call the canRemoveDataSource() method first.

UnsupportedDataSourceTypeError

The data source type is not supported by the current public API.

Validate dataSourceType before working with the API.

Error handling when working with view model attributes​

The following error classes may be thrown when creating, reading, or removing view model attributes.

Error class

Trigger

Solution

ViewModelAttributeAlreadyExistsError

Creating an attribute with an existing name.

Reuse the existing attribute or remove and recreate it if safe.

ViewModelAttributeNotFoundError

Removing or resolving an invalid attribute path.

Verify attribute name or path before removal.

ViewModelAttributeNotBoundError

Calling the getModelBinding() method for an attribute that is not bound.

Check attribute type and binding state before reading binding.

BoundViewModelAttributeRemovalError

Removing an attribute that is still referenced.

Call the canRemoveAttribute() method first and provide a user-friendly message.

UnsupportedViewModelAttributeDataError

Passing unsupported createAttribute() options.

Verify that the options correspond to constant, scalar binding, or collection binding.

Error handling when working with view node properties​

The following error classes may be thrown when reading or writing view node properties.

Error class

Trigger

Solution

UnsupportedViewNodePropertyTypeError

A view-node property contains an unsupported binding type.

Check the returned property type before processing it.


See also​

Working with collection attributes when implementing Freedom UI Designer setup area

Freedom UI Designer setup area for a custom Freedom UI component

Implement a Freedom UI Designer setup area for a custom Freedom UI component