@wix/auto-patterns 1.34.0 → 1.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -870,7 +870,7 @@ Custom collection page actions execute JavaScript code that you define for colle
870
870
  },
871
871
  successToast: 'Collection exported successfully',
872
872
  errorToast: (err, {retry}) => ({
873
- message: 'Export failed',
873
+ text: 'Export failed',
874
874
  action: { text: 'Retry', onClick: retry }
875
875
  })
876
876
  }
@@ -880,6 +880,60 @@ Custom collection page actions execute JavaScript code that you define for colle
880
880
  };
881
881
  ```
882
882
 
883
+ **⚠️ CRITICAL: Error Handling for HTTP Requests**
884
+
885
+ The example above uses SDK methods which don't require error handling. However, if your custom collection action makes HTTP requests, you MUST follow the error handling patterns:
886
+
887
+ **For Wix HTTP requests (httpClient, wix/data, wix/stores):**
888
+ ```typescript
889
+ import { errorHandler } from '@wix/essentials';
890
+
891
+ export const myCollectionAction: CustomActionCollectionPageActionResolver = (params) => {
892
+ const { actionParams, sdk } = params;
893
+ const { collectionId } = actionParams;
894
+
895
+ return {
896
+ label: 'My Collection Action',
897
+ icon: <MyIcon />,
898
+ onClick: () => {
899
+ // ✅ CORRECT: Wix API call wrapped with errorHandler
900
+ errorHandler.withErrorHandler(
901
+ async () => {
902
+ const response = await httpClient.request(
903
+ myWixApiCall({ collectionId })
904
+ );
905
+ return response.data;
906
+ },
907
+ {}
908
+ );
909
+ },
910
+ biName: 'my-collection-action'
911
+ };
912
+ };
913
+ ```
914
+
915
+ **For External API requests (fetch, axios, third-party):**
916
+ ```typescript
917
+ export const myCollectionAction: CustomActionCollectionPageActionResolver = (params) => {
918
+ const { actionParams, sdk } = params;
919
+ const { collectionId } = actionParams;
920
+
921
+ return {
922
+ label: 'My Collection Action',
923
+ icon: <MyIcon />,
924
+ onClick: () => {
925
+ // ✅ CORRECT: External API call - NO errorHandler needed
926
+ fetch(`https://api.external-service.com/endpoint/${collectionId}`)
927
+ .then(response => response.json())
928
+ .then(data => console.log('External API response:', data));
929
+ },
930
+ biName: 'my-collection-action'
931
+ };
932
+ };
933
+ ```
934
+
935
+ **Read the "Error Handling for HTTP Requests" section for complete guidance.**
936
+
883
937
  3. Export your action in `actions/index.tsx`:
884
938
  ```typescript
885
939
  import { exportCollection } from './exportCollection';
@@ -1096,7 +1150,7 @@ export const quickToggle: CustomActionCollectionPageActionOnRowClickResolver = (
1096
1150
  },
1097
1151
  successToast: `${item.name} toggled successfully`,
1098
1152
  errorToast: (err, {retry}) => ({
1099
- message: 'Toggle failed',
1153
+ text: 'Toggle failed',
1100
1154
  action: { text: 'Retry', onClick: retry }
1101
1155
  })
1102
1156
  });
@@ -1492,6 +1546,7 @@ Both properties are optional, but at least one should be provided for the Action
1492
1546
  - Browser interactions (alerts, downloads)
1493
1547
  - Complex operations
1494
1548
  - ⚠️ Requires implementation: Must register action in overrides
1549
+ - ⚠️ **CRITICAL: Error Handling Required** - When implementing custom actions that make HTTP requests, you MUST read the "Error Handling for HTTP Requests" section and apply the correct error handling patterns. Wix HTTP requests require `errorHandler.withErrorHandler`, while external API calls should NOT use errorHandler.
1495
1550
 
1496
1551
  ### Action Appearance: The `skin` Property
1497
1552
 
@@ -1591,7 +1646,7 @@ Custom actions execute JavaScript code that you define. These actions receive pa
1591
1646
  },
1592
1647
  successToast: 'Pet details downloaded',
1593
1648
  errorToast: (err, {retry}) => ({
1594
- message: 'Download failed',
1649
+ text: 'Download failed',
1595
1650
  action: { text: 'Retry', onClick: retry }
1596
1651
  })
1597
1652
  });
@@ -1601,6 +1656,53 @@ Custom actions execute JavaScript code that you define. These actions receive pa
1601
1656
  };
1602
1657
  ```
1603
1658
 
1659
+ **⚠️ CRITICAL: Error Handling for HTTP Requests**
1660
+
1661
+ The example above uses SDK methods which don't require error handling. However, if your custom action makes HTTP requests, you MUST follow the error handling patterns:
1662
+
1663
+ **For Wix HTTP requests (httpClient, wix/data, wix/stores):**
1664
+ ```typescript
1665
+ import { errorHandler } from '@wix/essentials';
1666
+
1667
+ export const myAction: CustomActionCellSecondaryActionResolver = (params) => {
1668
+ return {
1669
+ label: 'My Action',
1670
+ icon: <MyIcon />,
1671
+ onClick: () => {
1672
+ // ✅ CORRECT: Wix API call wrapped with errorHandler
1673
+ errorHandler.withErrorHandler(
1674
+ async () => {
1675
+ const response = await httpClient.request(
1676
+ myWixApiCall({ data: params.actionParams.item })
1677
+ );
1678
+ return response.data;
1679
+ },
1680
+ {}
1681
+ );
1682
+ },
1683
+ };
1684
+ };
1685
+ ```
1686
+
1687
+ **For External API requests (fetch, axios, third-party):**
1688
+ ```typescript
1689
+ export const myAction: CustomActionCellSecondaryActionResolver = (params) => {
1690
+ return {
1691
+ label: 'My Action',
1692
+ icon: <MyIcon />,
1693
+ onClick: () => {
1694
+ // ✅ CORRECT: External API call - NO errorHandler needed
1695
+ fetch('https://api.external-service.com/endpoint', {
1696
+ method: 'POST',
1697
+ body: JSON.stringify(params.actionParams.item)
1698
+ });
1699
+ },
1700
+ };
1701
+ };
1702
+ ```
1703
+
1704
+ **Read the "Error Handling for HTTP Requests" section for complete guidance.**
1705
+
1604
1706
  3. Export your action in `actions/index.tsx`:
1605
1707
  ```typescript
1606
1708
  import { downloadPetDetails } from './downloadPetDetails';
@@ -1661,7 +1763,7 @@ Custom actions execute JavaScript code that you define. These actions receive pa
1661
1763
  - Enable analytics tracking for user interactions
1662
1764
 
1663
1765
  2. The implementation must return a `ResolvedAction` object with:
1664
- - `label`: Text displayed for the action
1766
+ - `label`: Text displayed for the action
1665
1767
  - `icon`: An Icon component from "@wix/wix-ui-icons-common"
1666
1768
  - `onClick`: Handler function for the action
1667
1769
  - `biName`: Business intelligence name for analytics tracking. Must match the `biName` in your action configuration (required)
@@ -1790,7 +1892,12 @@ Custom bulk actions execute JavaScript code that you define for bulk operations.
1790
1892
  ```
1791
1893
 
1792
1894
  2. Create your bulk action handler in `bulkExportPets.tsx`:
1895
+
1896
+ **⚠️ CRITICAL: Before implementing, read the "Error Handling for HTTP Requests" section to understand when to use `errorHandler.withErrorHandler`.**
1897
+
1898
+ **Example 1: Bulk action with Wix API call (REQUIRES errorHandler)**
1793
1899
  ```typescript
1900
+ import { errorHandler } from '@wix/essentials';
1794
1901
  import { CustomBulkActionsActionResolver } from '@wix/auto-patterns';
1795
1902
  import { Download } from '@wix/wix-ui-icons-common';
1796
1903
  import React from 'react';
@@ -1804,43 +1911,92 @@ Custom bulk actions execute JavaScript code that you define for bulk operations.
1804
1911
  label: 'Export Selected',
1805
1912
  icon: <Download />,
1806
1913
  onClick: () => {
1807
- // sdk is provided to custom action resolvers (see SDK Utilities section)
1914
+ // CORRECT: Wix API call wrapped with errorHandler
1915
+ errorHandler.withErrorHandler(
1916
+ async () => {
1917
+ const response = await httpClient.request(
1918
+ bulkExportPetsData({
1919
+ petIds: selectedValues.map(pet => pet.id),
1920
+ totalCount: total
1921
+ })
1922
+ );
1923
+ return response.data;
1924
+ },
1925
+ {}
1926
+ );
1927
+ },
1928
+ biName: 'bulk-export-pets-action' // MANDATORY: For analytics tracking
1929
+ };
1930
+ };
1931
+ ```
1932
+
1933
+ **Example 2: Bulk action with External API call (NO errorHandler needed)**
1934
+ ```typescript
1935
+ import { CustomBulkActionsActionResolver } from '@wix/auto-patterns';
1936
+ import { Download } from '@wix/wix-ui-icons-common';
1937
+ import React from 'react';
1938
+
1939
+ export const bulkExportPets: CustomBulkActionsActionResolver = (params) => {
1940
+ const { actionParams, sdk } = params;
1941
+ const { selectedValues, total } = actionParams;
1942
+
1943
+ return {
1944
+ label: 'Export Selected',
1945
+ icon: <Download />,
1946
+ onClick: () => {
1947
+ // ✅ CORRECT: External API call - NO errorHandler needed
1948
+ const exportData = selectedValues.map(pet => ({
1949
+ name: pet.name,
1950
+ age: pet.age,
1951
+ owner: pet.owner
1952
+ }));
1953
+
1954
+ // Create and download CSV
1955
+ const csv = exportData.map(row => Object.values(row).join(',')).join('\n');
1956
+ const blob = new Blob([csv], { type: 'text/csv' });
1957
+ const url = URL.createObjectURL(blob);
1958
+ const a = document.createElement('a');
1959
+ a.href = url;
1960
+ a.download = 'pets-export.csv';
1961
+ a.click();
1962
+ },
1963
+ biName: 'bulk-export-pets-action' // MANDATORY: For analytics tracking
1964
+ };
1965
+ };
1966
+ ```
1967
+
1968
+ **Example 3: Bulk action using SDK methods (NO errorHandler needed)**
1969
+ ```typescript
1970
+ import { CustomBulkActionsActionResolver } from '@wix/auto-patterns';
1971
+ import { Download } from '@wix/wix-ui-icons-common';
1972
+ import React from 'react';
1973
+
1974
+ export const bulkExportPets: CustomBulkActionsActionResolver = (params) => {
1975
+ const { actionParams, sdk } = params;
1976
+ const { selectedValues, total } = actionParams;
1977
+
1978
+ return {
1979
+ label: 'Export Selected',
1980
+ icon: <Download />,
1981
+ onClick: () => {
1982
+ // ✅ CORRECT: SDK methods - NO errorHandler needed
1808
1983
  const optimisticActions = sdk.getOptimisticActions(sdk.collectionId);
1809
1984
  const schema = sdk.getSchema(sdk.collectionId);
1810
1985
 
1811
- // Example: Mark pets as exported
1812
1986
  const updatedItems = selectedValues.map(item => ({
1813
1987
  ...item,
1814
1988
  lastExported: new Date()
1815
1989
  }));
1816
1990
  optimisticActions.updateMany(updatedItems, {
1817
1991
  submit: async (items) => {
1818
- // Your export logic here + update server
1819
- const exportData = items.map(pet => ({
1820
- name: pet.name,
1821
- age: pet.age,
1822
- owner: pet.owner
1823
- }));
1824
-
1825
- // Create and download CSV
1826
- const csv = exportData.map(row => Object.values(row).join(',')).join('\n');
1827
- const blob = new Blob([csv], { type: 'text/csv' });
1828
- const url = URL.createObjectURL(blob);
1829
- const a = document.createElement('a');
1830
- a.href = url;
1831
- a.download = 'pets-export.csv';
1832
- a.click();
1833
-
1834
- // Update server with export timestamp
1835
- // Handle potential undefined schema
1836
1992
  if (schema) {
1837
1993
  return await schema.actions.update(items);
1838
1994
  }
1839
- return items; // fallback when schema is unavailable
1995
+ return items;
1840
1996
  },
1841
1997
  successToast: `${selectedValues.length} pets exported`,
1842
1998
  errorToast: (err, {retry}) => ({
1843
- message: 'Export failed',
1999
+ text: 'Export failed',
1844
2000
  action: { text: 'Retry', onClick: retry }
1845
2001
  })
1846
2002
  });
@@ -1850,6 +2006,8 @@ Custom bulk actions execute JavaScript code that you define for bulk operations.
1850
2006
  };
1851
2007
  ```
1852
2008
 
2009
+ **Read the "Error Handling for HTTP Requests" section for complete guidance.**
2010
+
1853
2011
  3. Export your action in `actions/index.tsx`:
1854
2012
  ```typescript
1855
2013
  import { bulkExportPets } from './bulkExportPets';
@@ -2524,6 +2682,64 @@ The `CustomEntityPageActionResolver` type is used to implement custom actions fo
2524
2682
 
2525
2683
  #### Function Signature
2526
2684
 
2685
+ **⚠️ CRITICAL: Before implementing, read the "Error Handling for HTTP Requests" section to understand when to use `errorHandler.withErrorHandler`.**
2686
+
2687
+ **Example 1: EntityPage action with Wix API call (REQUIRES errorHandler)**
2688
+ ```typescript
2689
+ import { errorHandler } from '@wix/essentials';
2690
+ import { CustomEntityPageActionResolver } from '@wix/auto-patterns/types';
2691
+
2692
+ export const sendEmail: CustomEntityPageActionResolver = (params) => {
2693
+ const { actionParams: { entity, form } , sdk } = params;
2694
+
2695
+ return {
2696
+ label: 'Send Email',
2697
+ icon: <EmailIcon />, // required
2698
+ onClick: () => {
2699
+ // ✅ CORRECT: Wix API call wrapped with errorHandler
2700
+ errorHandler.withErrorHandler(
2701
+ async () => {
2702
+ const response = await httpClient.request(
2703
+ sendEmailToEntity({ entityId: entity.id, email: entity.email })
2704
+ );
2705
+ return response.data;
2706
+ },
2707
+ {}
2708
+ );
2709
+ },
2710
+ biName: 'send-email-action' // MANDATORY: For analytics tracking
2711
+ };
2712
+ };
2713
+ ```
2714
+
2715
+ **Example 2: EntityPage action with External API call (NO errorHandler needed)**
2716
+ ```typescript
2717
+ import { CustomEntityPageActionResolver } from '@wix/auto-patterns/types';
2718
+
2719
+ export const exportData: CustomEntityPageActionResolver = (params) => {
2720
+ const { actionParams: { entity, form } , sdk } = params;
2721
+
2722
+ return {
2723
+ label: 'Export Data',
2724
+ icon: <ExportIcon />, // required
2725
+ onClick: () => {
2726
+ // ✅ CORRECT: External API call - NO errorHandler needed
2727
+ fetch(`https://api.external-service.com/export/${entity.id}`)
2728
+ .then(response => response.blob())
2729
+ .then(blob => {
2730
+ const url = URL.createObjectURL(blob);
2731
+ const a = document.createElement('a');
2732
+ a.href = url;
2733
+ a.download = `entity-${entity.id}.pdf`;
2734
+ a.click();
2735
+ });
2736
+ },
2737
+ biName: 'export-data-action' // MANDATORY: For analytics tracking
2738
+ };
2739
+ };
2740
+ ```
2741
+
2742
+ **Example 3: EntityPage action using SDK methods (NO errorHandler needed)**
2527
2743
  ```typescript
2528
2744
  import { CustomEntityPageActionResolver } from '@wix/auto-patterns/types';
2529
2745
 
@@ -2534,13 +2750,32 @@ export const myMoreAction: CustomEntityPageActionResolver = (params) => {
2534
2750
  label: 'My More Action',
2535
2751
  icon: <MyIcon />, // required
2536
2752
  onClick: () => {
2537
- // Your custom logic here
2753
+ // CORRECT: SDK methods - NO errorHandler needed
2754
+ const optimisticActions = sdk.getOptimisticActions(sdk.collectionId);
2755
+ const schema = sdk.getSchema(sdk.collectionId);
2756
+
2757
+ const updatedEntity = { ...entity, lastAction: new Date() };
2758
+ optimisticActions.updateOne(updatedEntity, {
2759
+ submit: async (items) => {
2760
+ if (schema) {
2761
+ return await schema.actions.update(items[0]);
2762
+ }
2763
+ return items[0];
2764
+ },
2765
+ successToast: 'Action completed successfully',
2766
+ errorToast: (err, {retry}) => ({
2767
+ text: 'Action failed',
2768
+ action: { text: 'Retry', onClick: retry }
2769
+ })
2770
+ });
2538
2771
  },
2539
2772
  biName: 'my-more-action' // MANDATORY: For analytics tracking
2540
2773
  };
2541
2774
  };
2542
2775
  ```
2543
2776
 
2777
+ **Read the "Error Handling for HTTP Requests" section for complete guidance.**
2778
+
2544
2779
  - **entity**: The current entity data (all field values). In actionParams.
2545
2780
  - **form**: The react-hook-form instance for the entity page. In actionParams.
2546
2781
  - **sdk**: The AutoPatterns SDK (see SDK Utilities section).
@@ -2580,6 +2815,8 @@ The `CustomEntityPageActionResolver` enables you to add custom, contextual actio
2580
2815
 
2581
2816
  View mode supports the complete collection-style actions API, providing maximum flexibility for entity operations.
2582
2817
 
2818
+ **⚠️ CRITICAL: Error Handling for Custom Actions** - When implementing custom actions (type: "custom") in view mode, you MUST read the "Error Handling for HTTP Requests" section and apply the correct error handling patterns. Wix HTTP requests require `errorHandler.withErrorHandler`, while external API calls should NOT use errorHandler.
2819
+
2583
2820
  ## Supported Action Types
2584
2821
 
2585
2822
  ### Primary Actions
@@ -3027,6 +3264,7 @@ export const DataUpdateModal: React.FC = () => {
3027
3264
 
3028
3265
  - **Custom overrides are restricted to the defined areas only** - attempting to override or modify any other aspect of `AutoPatternsApp` is prohibited and can cause unexpected behavior
3029
3266
  - **Always verify override implementation** - when implementing custom overrides, you MUST ensure they are correctly imported and passed to the `AutoPatternsOverridesProvider`
3267
+ - **⚠️ CRITICAL: READ ERROR HANDLING DOCUMENTATION FIRST** - Before implementing ANY custom action (ActionCell, BulkActions, CollectionPage actions, EntityPage actions, or Custom Data Sources), you MUST read the "Error Handling for HTTP Requests" section and apply the correct error handling patterns. This is mandatory for all AI agents.
3030
3268
  - **CRITICAL: Error handling for custom actions** - Custom actions that make external API calls (using `fetch()`, `axios`, etc.) should NOT use `errorHandler.withErrorHandler`. Only Wix HTTP requests (httpClient from @wix/essentials, Wix APIs like wix/data and wix/stores, and httpClient.fetchWithAuth()) require errorHandler wrapping. See the "Error Handling for HTTP Requests" section for details.
3031
3269
 
3032
3270
  The `AutoPatternsOverridesProvider` allows you to inject custom code to override default behaviors or add additional functionality. Below are the areas where overrides can be applied:
@@ -4184,17 +4422,26 @@ Slots provide a powerful way to enhance collection pages with custom functionali
4184
4422
 
4185
4423
  # Error Handling for HTTP Requests
4186
4424
 
4425
+ **⚠️ CRITICAL FOR AI AGENTS**: When creating or updating ANY custom actions (ActionCell, BulkActions, CollectionPage actions, EntityPage actions, or Custom Data Sources), you **MUST ALWAYS** read this error handling documentation first and apply the correct error handling patterns.
4426
+
4427
+ **⚠️ MANDATORY WORKFLOW FOR AI AGENTS:**
4428
+ 1. **BEFORE** implementing any custom action, read this entire error handling documentation
4429
+ 2. **IDENTIFY** what type of HTTP requests (if any) your action will make
4430
+ 3. **APPLY** the correct error handling pattern based on the request type
4431
+ 4. **VERIFY** your implementation follows the validation checklist below
4432
+ 5. **NEVER** skip this process - it's critical for proper error handling
4433
+
4187
4434
  **⚠️ CRITICAL**: When implementing custom data sources that make HTTP requests, you **MUST** wrap specific HTTP calls with proper error handling. This ensures consistent error management, prevents unhandled promise rejections, and provides better user experience.
4188
4435
 
4189
4436
  ## What Requires Error Handling
4190
4437
 
4191
- **ONLY the following HTTP requests** in your custom data source actions must be wrapped with `errorHandler`:
4438
+ **ONLY the following HTTP requests** in your custom data source actions must be wrapped with `errorHandler.withErrorHandler`:
4192
4439
 
4193
4440
  - **httpClient from @wix/essentials** (e.g., `httpClient.request(getDummyEntity(...))`)
4194
4441
  - **Wix APIs** (e.g., `wix/data`, `wix/stores`, `items.get()`, `items.insert()`, `collections.getDataCollection()`)
4195
4442
  - **httpClient.fetchWithAuth()** calls
4196
4443
 
4197
- **DO NOT use errorHandler with:**
4444
+ **DO NOT use errorHandler.withErrorHandler with:**
4198
4445
 
4199
4446
  - **External API calls** using `fetch()`, `axios.get()`, or other HTTP libraries
4200
4447
  - **Custom HTTP clients** (e.g., any non-Wix HTTP request library)
@@ -4202,6 +4449,20 @@ Slots provide a powerful way to enhance collection pages with custom functionali
4202
4449
 
4203
4450
  **EXCEPTION**: SDK actions that you get from the AutoPatterns SDK (e.g., `sdk.getOptimisticActions()`, `sdk.getSchema()`) do NOT need error handling as they are already handled internally.
4204
4451
 
4452
+ ## ⚠️ CRITICAL: When to Apply Error Handling
4453
+
4454
+ **ALWAYS apply error handling when:**
4455
+
4456
+ 1. **Creating Custom Data Sources** - All HTTP requests in data source actions must be wrapped
4457
+ 2. **Implementing FQDN-based Custom Data Sources** - All Wix API calls must be wrapped
4458
+ 3. **Making any Wix HTTP requests** in custom actions (ActionCell, BulkActions, etc.)
4459
+
4460
+ **NEVER apply error handling when:**
4461
+
4462
+ 1. **Using external APIs** (fetch, axios, third-party libraries)
4463
+ 2. **Using AutoPatterns SDK methods** (sdk.getOptimisticActions, sdk.getSchema, etc.)
4464
+ 3. **Making non-HTTP operations** (local computations, form validations, etc.)
4465
+
4205
4466
  ## Why Error Handling is Required
4206
4467
 
4207
4468
  Custom data sources often make HTTP requests to Wix APIs and services. Without proper error handling:
@@ -4225,7 +4486,7 @@ npm install @wix/essentials
4225
4486
 
4226
4487
  ### Basic Error Handling Pattern
4227
4488
 
4228
- Wrap Wix HTTP requests in your custom data source actions with `errorHandler.withErrorHandler`:
4489
+ **⚠️ MANDATORY**: Wrap Wix HTTP requests in your custom data source actions with `errorHandler.withErrorHandler`:
4229
4490
 
4230
4491
  ```typescript
4231
4492
  import { errorHandler } from '@wix/essentials';
@@ -4246,6 +4507,62 @@ actions: {
4246
4507
  }
4247
4508
  ```
4248
4509
 
4510
+ ### ⚠️ CRITICAL: Error Handling in Custom Actions
4511
+
4512
+ **When implementing ANY custom action (ActionCell, BulkActions, CollectionPage actions, EntityPage actions), you MUST:**
4513
+
4514
+ 1. **Check if your action makes Wix HTTP requests**
4515
+ 2. **If YES**: Wrap the HTTP request with `errorHandler.withErrorHandler`
4516
+ 3. **If NO**: Do not use errorHandler (e.g., for external APIs, SDK methods, local operations)
4517
+
4518
+ **Example: Custom ActionCell with Wix API call**
4519
+ ```typescript
4520
+ import { errorHandler } from '@wix/essentials';
4521
+
4522
+ export const myCustomAction: CustomActionCellActionResolver = (params) => {
4523
+ const { actionParams, sdk } = params;
4524
+ const { item } = actionParams;
4525
+
4526
+ return {
4527
+ label: 'Update Status',
4528
+ icon: <UpdateIcon />,
4529
+ onClick: () => {
4530
+ // ✅ CORRECT: Wix API call wrapped with errorHandler
4531
+ errorHandler.withErrorHandler(
4532
+ async () => {
4533
+ const response = await httpClient.request(
4534
+ updateEntityStatus({ entityId: item.id, status: 'active' })
4535
+ );
4536
+ return response.data;
4537
+ },
4538
+ {}
4539
+ );
4540
+ },
4541
+ };
4542
+ };
4543
+ ```
4544
+
4545
+ **Example: Custom ActionCell with External API call**
4546
+ ```typescript
4547
+ export const myCustomAction: CustomActionCellActionResolver = (params) => {
4548
+ const { actionParams, sdk } = params;
4549
+ const { item } = actionParams;
4550
+
4551
+ return {
4552
+ label: 'Send to External Service',
4553
+ icon: <SendIcon />,
4554
+ onClick: () => {
4555
+ // ✅ CORRECT: External API call - NO errorHandler needed
4556
+ fetch('https://api.external-service.com/send', {
4557
+ method: 'POST',
4558
+ body: JSON.stringify({ data: item }),
4559
+ headers: { 'Content-Type': 'application/json' }
4560
+ });
4561
+ },
4562
+ };
4563
+ };
4564
+ ```
4565
+
4249
4566
  ### Examples of HTTP Requests That Need Error Handling
4250
4567
 
4251
4568
  **httpClient from @wix/essentials:**
@@ -4307,13 +4624,269 @@ The error handling in your custom data source integrates seamlessly with AutoPat
4307
4624
  3. **Loading States**: Proper loading states during HTTP requests
4308
4625
  4. **Error Boundaries**: Errors are caught and handled gracefully
4309
4626
 
4310
- ## Validation Checklist
4627
+ ## ⚠️ AI AGENT VALIDATION CHECKLIST
4628
+
4629
+ **BEFORE implementing ANY custom action or data source, AI agents MUST verify:**
4630
+
4631
+ ### ✅ Error Handling Requirements
4632
+ - **httpClient from @wix/essentials** is wrapped with `errorHandler.withErrorHandler`
4633
+ - **Wix APIs (wix/data, wix/stores, etc)** are wrapped with `errorHandler.withErrorHandler`
4634
+ - **httpClient.fetchWithAuth()** calls are wrapped with `errorHandler.withErrorHandler`
4635
+ - **External API calls are NOT wrapped** with errorHandler (e.g., fetch(), axios, third-party HTTP clients)
4636
+ - **SDK actions are used directly** without error handling (e.g., `sdk.getOptimisticActions()`, `sdk.getSchema()`)
4637
+ - **@wix/essentials** is installed as a dependency
4638
+
4639
+ ### ✅ Implementation Checklist
4640
+ - **Read this error handling documentation** before implementing any custom action
4641
+ - **Identify the type of HTTP request** being made (Wix vs External)
4642
+ - **Apply the correct error handling pattern** based on the request type
4643
+ - **Test error scenarios** to ensure proper error handling
4644
+ - **Verify error messages** are user-friendly and actionable
4645
+
4646
+ ### ✅ Common Mistakes to Avoid
4647
+ - ❌ **NEVER** wrap external API calls (fetch, axios) with errorHandler
4648
+ - ❌ **NEVER** wrap SDK methods (sdk.getOptimisticActions) with errorHandler
4649
+ - ❌ **NEVER** forget to wrap Wix HTTP requests with errorHandler
4650
+ - ❌ **NEVER** implement custom actions without reading this documentation first
4651
+
4652
+ ## Quick Decision Tree for AI Agents
4653
+
4654
+ **When implementing custom actions, ask:**
4655
+
4656
+ 1. **Does this action make HTTP requests?**
4657
+ - **NO** → No error handling needed
4658
+ - **YES** → Go to step 2
4659
+
4660
+ 2. **What type of HTTP request?**
4661
+ - **Wix APIs** (httpClient, wix/data, wix/stores) → **WRAP with errorHandler.withErrorHandler**
4662
+ - **External APIs** (fetch, axios, third-party) → **NO errorHandler needed**
4663
+ - **SDK methods** (sdk.getOptimisticActions, sdk.getSchema) → **NO errorHandler needed**
4664
+
4665
+ 3. **Verify implementation:**
4666
+ - **Wix requests** are wrapped with `errorHandler.withErrorHandler`
4667
+ - **External requests** are NOT wrapped
4668
+ - **SDK methods** are used directly
4669
+
4670
+ ## Complete Examples for All Custom Action Types
4311
4671
 
4312
- Before deploying your custom data source, ensure:
4672
+ ### ActionCell Custom Actions
4313
4673
 
4314
- **httpClient from @wix/essentials** is wrapped with `errorHandler.withErrorHandler`
4315
- ✅ **Wix APIs (wix/data, wix/stores, etc)** are wrapped with `errorHandler.withErrorHandler`
4316
- **httpClient.fetchWithAuth()** calls are wrapped with `errorHandler.withErrorHandler`
4317
- **External API calls are NOT wrapped** with errorHandler (e.g., fetch(), axios, third-party HTTP clients)
4318
- ✅ **SDK actions are used directly** without error handling (e.g., `sdk.getOptimisticActions()`, `sdk.getSchema()`)
4319
- **@wix/essentials** is installed as a dependency
4674
+ **Example 1: ActionCell with Wix API call (REQUIRES errorHandler)**
4675
+ ```typescript
4676
+ import { errorHandler } from '@wix/essentials';
4677
+ import { CustomActionCellActionResolver } from '@wix/auto-patterns';
4678
+
4679
+ export const updateEntityStatus: CustomActionCellActionResolver = (params) => {
4680
+ const { actionParams, sdk } = params;
4681
+ const { item } = actionParams;
4682
+
4683
+ return {
4684
+ label: 'Update Status',
4685
+ icon: <UpdateIcon />,
4686
+ onClick: () => {
4687
+ // ✅ CORRECT: Wix API call wrapped with errorHandler
4688
+ errorHandler.withErrorHandler(
4689
+ async () => {
4690
+ const response = await httpClient.request(
4691
+ updateEntityStatus({ entityId: item.id, status: 'active' })
4692
+ );
4693
+ return response.data;
4694
+ },
4695
+ {}
4696
+ );
4697
+ },
4698
+ };
4699
+ };
4700
+ ```
4701
+
4702
+ **Example 2: ActionCell with External API call (NO errorHandler needed)**
4703
+ ```typescript
4704
+ import { CustomActionCellActionResolver } from '@wix/auto-patterns';
4705
+
4706
+ export const sendToExternalService: CustomActionCellActionResolver = (params) => {
4707
+ const { actionParams, sdk } = params;
4708
+ const { item } = actionParams;
4709
+
4710
+ return {
4711
+ label: 'Send to External Service',
4712
+ icon: <SendIcon />,
4713
+ onClick: () => {
4714
+ // ✅ CORRECT: External API call - NO errorHandler needed
4715
+ fetch('https://api.external-service.com/send', {
4716
+ method: 'POST',
4717
+ body: JSON.stringify({ data: item }),
4718
+ headers: { 'Content-Type': 'application/json' }
4719
+ });
4720
+ },
4721
+ };
4722
+ };
4723
+ ```
4724
+
4725
+ ### BulkActions Custom Actions
4726
+
4727
+ **Example 3: BulkAction with Wix API call (REQUIRES errorHandler)**
4728
+ ```typescript
4729
+ import { errorHandler } from '@wix/essentials';
4730
+ import { CustomBulkActionsActionResolver } from '@wix/auto-patterns';
4731
+
4732
+ export const bulkUpdateStatus: CustomBulkActionsActionResolver = (params) => {
4733
+ const { actionParams, sdk } = params;
4734
+ const { selectedValues } = actionParams;
4735
+
4736
+ return {
4737
+ label: 'Bulk Update Status',
4738
+ icon: <BulkUpdateIcon />,
4739
+ onClick: () => {
4740
+ // ✅ CORRECT: Wix API call wrapped with errorHandler
4741
+ errorHandler.withErrorHandler(
4742
+ async () => {
4743
+ const response = await httpClient.request(
4744
+ bulkUpdateEntityStatus({
4745
+ entityIds: selectedValues.map(item => item.id),
4746
+ status: 'active'
4747
+ })
4748
+ );
4749
+ return response.data;
4750
+ },
4751
+ {}
4752
+ );
4753
+ },
4754
+ };
4755
+ };
4756
+ ```
4757
+
4758
+ ### CollectionPage Custom Actions
4759
+
4760
+ **Example 4: CollectionPage action with Wix API call (REQUIRES errorHandler)**
4761
+ ```typescript
4762
+ import { errorHandler } from '@wix/essentials';
4763
+ import { CustomActionCollectionPageActionResolver } from '@wix/auto-patterns';
4764
+
4765
+ export const exportCollection: CustomActionCollectionPageActionResolver = (params) => {
4766
+ const { actionParams, sdk } = params;
4767
+ const { collectionId } = actionParams;
4768
+
4769
+ return {
4770
+ label: 'Export Collection',
4771
+ icon: <ExportIcon />,
4772
+ onClick: () => {
4773
+ // ✅ CORRECT: Wix API call wrapped with errorHandler
4774
+ errorHandler.withErrorHandler(
4775
+ async () => {
4776
+ const response = await httpClient.request(
4777
+ exportCollectionData({ collectionId })
4778
+ );
4779
+ return response.data;
4780
+ },
4781
+ {}
4782
+ );
4783
+ },
4784
+ };
4785
+ };
4786
+ ```
4787
+
4788
+ ### EntityPage Custom Actions
4789
+
4790
+ **Example 5: EntityPage action with Wix API call (REQUIRES errorHandler)**
4791
+ ```typescript
4792
+ import { errorHandler } from '@wix/essentials';
4793
+ import { CustomEntityPageMoreActionsActionResolver } from '@wix/auto-patterns';
4794
+
4795
+ export const sendEmail: CustomEntityPageMoreActionsActionResolver = (params) => {
4796
+ const { actionParams, sdk } = params;
4797
+ const { entity } = actionParams;
4798
+
4799
+ return {
4800
+ label: 'Send Email',
4801
+ icon: <EmailIcon />,
4802
+ onClick: () => {
4803
+ // ✅ CORRECT: Wix API call wrapped with errorHandler
4804
+ errorHandler.withErrorHandler(
4805
+ async () => {
4806
+ const response = await httpClient.request(
4807
+ sendEmailToEntity({ entityId: entity.id, email: entity.email })
4808
+ );
4809
+ return response.data;
4810
+ },
4811
+ {}
4812
+ );
4813
+ },
4814
+ };
4815
+ };
4816
+ ```
4817
+
4818
+ ### Custom Data Sources
4819
+
4820
+ **Example 6: Custom Data Source with Wix API calls (REQUIRES errorHandler)**
4821
+ ```typescript
4822
+ import { errorHandler } from '@wix/essentials';
4823
+
4824
+ export const myCustomDataSource = async (collectionId: string, context: any) => {
4825
+ return {
4826
+ id: 'myCustomCollection',
4827
+ fields: {
4828
+ // ... field definitions
4829
+ },
4830
+ idField: 'id',
4831
+ actions: {
4832
+ get: async (entityId: string) => {
4833
+ // ✅ CORRECT: Wix API call wrapped with errorHandler
4834
+ return errorHandler.withErrorHandler(
4835
+ async () => {
4836
+ const response = await httpClient.request(
4837
+ getDummyEntity({ dummyEntityId: entityId })
4838
+ );
4839
+ return response.data.dummyEntity;
4840
+ },
4841
+ {}
4842
+ );
4843
+ },
4844
+ create: async (newEntity: any) => {
4845
+ // ✅ CORRECT: Wix API call wrapped with errorHandler
4846
+ return errorHandler.withErrorHandler(
4847
+ async () => {
4848
+ const response = await httpClient.request(
4849
+ createDummyEntity({ dummyEntity: newEntity })
4850
+ );
4851
+ return response.data.dummyEntity;
4852
+ },
4853
+ {}
4854
+ );
4855
+ },
4856
+ // ... other actions
4857
+ },
4858
+ };
4859
+ };
4860
+ ```
4861
+
4862
+ ### Actions Using SDK Methods (NO errorHandler needed)
4863
+
4864
+ **Example 7: Action using SDK methods (NO errorHandler needed)**
4865
+ ```typescript
4866
+ import { CustomActionCellActionResolver } from '@wix/auto-patterns';
4867
+
4868
+ export const quickUpdate: CustomActionCellActionResolver = (params) => {
4869
+ const { actionParams, sdk } = params;
4870
+ const { item } = actionParams;
4871
+
4872
+ return {
4873
+ label: 'Quick Update',
4874
+ icon: <QuickUpdateIcon />,
4875
+ onClick: () => {
4876
+ // ✅ CORRECT: SDK methods - NO errorHandler needed
4877
+ const optimisticActions = sdk.getOptimisticActions(sdk.collectionId);
4878
+ const schema = sdk.getSchema(sdk.collectionId);
4879
+
4880
+ const updatedItem = { ...item, lastUpdated: new Date() };
4881
+ optimisticActions.updateOne(updatedItem, {
4882
+ submit: async (items) => schema.actions.update(items[0]),
4883
+ successToast: 'Item updated successfully',
4884
+ errorToast: (err, {retry}) => ({
4885
+ text: 'Update failed',
4886
+ action: { text: 'Retry', onClick: retry }
4887
+ })
4888
+ });
4889
+ },
4890
+ };
4891
+ };
4892
+ ```