@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.
@@ -1,16 +1,25 @@
1
1
  # Error Handling for HTTP Requests
2
2
 
3
+ **⚠️ 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.
4
+
5
+ **⚠️ MANDATORY WORKFLOW FOR AI AGENTS:**
6
+ 1. **BEFORE** implementing any custom action, read this entire error handling documentation
7
+ 2. **IDENTIFY** what type of HTTP requests (if any) your action will make
8
+ 3. **APPLY** the correct error handling pattern based on the request type
9
+ 4. **VERIFY** your implementation follows the validation checklist below
10
+ 5. **NEVER** skip this process - it's critical for proper error handling
11
+
3
12
  **⚠️ 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.
4
13
 
5
14
  ## What Requires Error Handling
6
15
 
7
- **ONLY the following HTTP requests** in your custom data source actions must be wrapped with `errorHandler`:
16
+ **ONLY the following HTTP requests** in your custom data source actions must be wrapped with `errorHandler.withErrorHandler`:
8
17
 
9
18
  - **httpClient from @wix/essentials** (e.g., `httpClient.request(getDummyEntity(...))`)
10
19
  - **Wix APIs** (e.g., `wix/data`, `wix/stores`, `items.get()`, `items.insert()`, `collections.getDataCollection()`)
11
20
  - **httpClient.fetchWithAuth()** calls
12
21
 
13
- **DO NOT use errorHandler with:**
22
+ **DO NOT use errorHandler.withErrorHandler with:**
14
23
 
15
24
  - **External API calls** using `fetch()`, `axios.get()`, or other HTTP libraries
16
25
  - **Custom HTTP clients** (e.g., any non-Wix HTTP request library)
@@ -18,6 +27,20 @@
18
27
 
19
28
  **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.
20
29
 
30
+ ## ⚠️ CRITICAL: When to Apply Error Handling
31
+
32
+ **ALWAYS apply error handling when:**
33
+
34
+ 1. **Creating Custom Data Sources** - All HTTP requests in data source actions must be wrapped
35
+ 2. **Implementing FQDN-based Custom Data Sources** - All Wix API calls must be wrapped
36
+ 3. **Making any Wix HTTP requests** in custom actions (ActionCell, BulkActions, etc.)
37
+
38
+ **NEVER apply error handling when:**
39
+
40
+ 1. **Using external APIs** (fetch, axios, third-party libraries)
41
+ 2. **Using AutoPatterns SDK methods** (sdk.getOptimisticActions, sdk.getSchema, etc.)
42
+ 3. **Making non-HTTP operations** (local computations, form validations, etc.)
43
+
21
44
  ## Why Error Handling is Required
22
45
 
23
46
  Custom data sources often make HTTP requests to Wix APIs and services. Without proper error handling:
@@ -41,7 +64,7 @@ npm install @wix/essentials
41
64
 
42
65
  ### Basic Error Handling Pattern
43
66
 
44
- Wrap Wix HTTP requests in your custom data source actions with `errorHandler.withErrorHandler`:
67
+ **⚠️ MANDATORY**: Wrap Wix HTTP requests in your custom data source actions with `errorHandler.withErrorHandler`:
45
68
 
46
69
  ```typescript
47
70
  import { errorHandler } from '@wix/essentials';
@@ -62,6 +85,62 @@ actions: {
62
85
  }
63
86
  ```
64
87
 
88
+ ### ⚠️ CRITICAL: Error Handling in Custom Actions
89
+
90
+ **When implementing ANY custom action (ActionCell, BulkActions, CollectionPage actions, EntityPage actions), you MUST:**
91
+
92
+ 1. **Check if your action makes Wix HTTP requests**
93
+ 2. **If YES**: Wrap the HTTP request with `errorHandler.withErrorHandler`
94
+ 3. **If NO**: Do not use errorHandler (e.g., for external APIs, SDK methods, local operations)
95
+
96
+ **Example: Custom ActionCell with Wix API call**
97
+ ```typescript
98
+ import { errorHandler } from '@wix/essentials';
99
+
100
+ export const myCustomAction: CustomActionCellActionResolver = (params) => {
101
+ const { actionParams, sdk } = params;
102
+ const { item } = actionParams;
103
+
104
+ return {
105
+ label: 'Update Status',
106
+ icon: <UpdateIcon />,
107
+ onClick: () => {
108
+ // ✅ CORRECT: Wix API call wrapped with errorHandler
109
+ errorHandler.withErrorHandler(
110
+ async () => {
111
+ const response = await httpClient.request(
112
+ updateEntityStatus({ entityId: item.id, status: 'active' })
113
+ );
114
+ return response.data;
115
+ },
116
+ {}
117
+ );
118
+ },
119
+ };
120
+ };
121
+ ```
122
+
123
+ **Example: Custom ActionCell with External API call**
124
+ ```typescript
125
+ export const myCustomAction: CustomActionCellActionResolver = (params) => {
126
+ const { actionParams, sdk } = params;
127
+ const { item } = actionParams;
128
+
129
+ return {
130
+ label: 'Send to External Service',
131
+ icon: <SendIcon />,
132
+ onClick: () => {
133
+ // ✅ CORRECT: External API call - NO errorHandler needed
134
+ fetch('https://api.external-service.com/send', {
135
+ method: 'POST',
136
+ body: JSON.stringify({ data: item }),
137
+ headers: { 'Content-Type': 'application/json' }
138
+ });
139
+ },
140
+ };
141
+ };
142
+ ```
143
+
65
144
  ### Examples of HTTP Requests That Need Error Handling
66
145
 
67
146
  **httpClient from @wix/essentials:**
@@ -123,13 +202,269 @@ The error handling in your custom data source integrates seamlessly with AutoPat
123
202
  3. **Loading States**: Proper loading states during HTTP requests
124
203
  4. **Error Boundaries**: Errors are caught and handled gracefully
125
204
 
126
- ## Validation Checklist
205
+ ## ⚠️ AI AGENT VALIDATION CHECKLIST
206
+
207
+ **BEFORE implementing ANY custom action or data source, AI agents MUST verify:**
208
+
209
+ ### ✅ Error Handling Requirements
210
+ - **httpClient from @wix/essentials** is wrapped with `errorHandler.withErrorHandler`
211
+ - **Wix APIs (wix/data, wix/stores, etc)** are wrapped with `errorHandler.withErrorHandler`
212
+ - **httpClient.fetchWithAuth()** calls are wrapped with `errorHandler.withErrorHandler`
213
+ - **External API calls are NOT wrapped** with errorHandler (e.g., fetch(), axios, third-party HTTP clients)
214
+ - **SDK actions are used directly** without error handling (e.g., `sdk.getOptimisticActions()`, `sdk.getSchema()`)
215
+ - **@wix/essentials** is installed as a dependency
216
+
217
+ ### ✅ Implementation Checklist
218
+ - **Read this error handling documentation** before implementing any custom action
219
+ - **Identify the type of HTTP request** being made (Wix vs External)
220
+ - **Apply the correct error handling pattern** based on the request type
221
+ - **Test error scenarios** to ensure proper error handling
222
+ - **Verify error messages** are user-friendly and actionable
223
+
224
+ ### ✅ Common Mistakes to Avoid
225
+ - ❌ **NEVER** wrap external API calls (fetch, axios) with errorHandler
226
+ - ❌ **NEVER** wrap SDK methods (sdk.getOptimisticActions) with errorHandler
227
+ - ❌ **NEVER** forget to wrap Wix HTTP requests with errorHandler
228
+ - ❌ **NEVER** implement custom actions without reading this documentation first
229
+
230
+ ## Quick Decision Tree for AI Agents
231
+
232
+ **When implementing custom actions, ask:**
127
233
 
128
- Before deploying your custom data source, ensure:
234
+ 1. **Does this action make HTTP requests?**
235
+ - **NO** → No error handling needed
236
+ - **YES** → Go to step 2
237
+
238
+ 2. **What type of HTTP request?**
239
+ - **Wix APIs** (httpClient, wix/data, wix/stores) → **WRAP with errorHandler.withErrorHandler**
240
+ - **External APIs** (fetch, axios, third-party) → **NO errorHandler needed**
241
+ - **SDK methods** (sdk.getOptimisticActions, sdk.getSchema) → **NO errorHandler needed**
242
+
243
+ 3. **Verify implementation:**
244
+ - **Wix requests** are wrapped with `errorHandler.withErrorHandler`
245
+ - **External requests** are NOT wrapped
246
+ - **SDK methods** are used directly
247
+
248
+ ## Complete Examples for All Custom Action Types
249
+
250
+ ### ActionCell Custom Actions
251
+
252
+ **Example 1: ActionCell with Wix API call (REQUIRES errorHandler)**
253
+ ```typescript
254
+ import { errorHandler } from '@wix/essentials';
255
+ import { CustomActionCellActionResolver } from '@wix/auto-patterns';
256
+
257
+ export const updateEntityStatus: CustomActionCellActionResolver = (params) => {
258
+ const { actionParams, sdk } = params;
259
+ const { item } = actionParams;
260
+
261
+ return {
262
+ label: 'Update Status',
263
+ icon: <UpdateIcon />,
264
+ onClick: () => {
265
+ // ✅ CORRECT: Wix API call wrapped with errorHandler
266
+ errorHandler.withErrorHandler(
267
+ async () => {
268
+ const response = await httpClient.request(
269
+ updateEntityStatus({ entityId: item.id, status: 'active' })
270
+ );
271
+ return response.data;
272
+ },
273
+ {}
274
+ );
275
+ },
276
+ };
277
+ };
278
+ ```
129
279
 
130
- **httpClient from @wix/essentials** is wrapped with `errorHandler.withErrorHandler`
131
- ✅ **Wix APIs (wix/data, wix/stores, etc)** are wrapped with `errorHandler.withErrorHandler`
132
- **httpClient.fetchWithAuth()** calls are wrapped with `errorHandler.withErrorHandler`
133
- ✅ **External API calls are NOT wrapped** with errorHandler (e.g., fetch(), axios, third-party HTTP clients)
134
- **SDK actions are used directly** without error handling (e.g., `sdk.getOptimisticActions()`, `sdk.getSchema()`)
135
- **@wix/essentials** is installed as a dependency
280
+ **Example 2: ActionCell with External API call (NO errorHandler needed)**
281
+ ```typescript
282
+ import { CustomActionCellActionResolver } from '@wix/auto-patterns';
283
+
284
+ export const sendToExternalService: CustomActionCellActionResolver = (params) => {
285
+ const { actionParams, sdk } = params;
286
+ const { item } = actionParams;
287
+
288
+ return {
289
+ label: 'Send to External Service',
290
+ icon: <SendIcon />,
291
+ onClick: () => {
292
+ // ✅ CORRECT: External API call - NO errorHandler needed
293
+ fetch('https://api.external-service.com/send', {
294
+ method: 'POST',
295
+ body: JSON.stringify({ data: item }),
296
+ headers: { 'Content-Type': 'application/json' }
297
+ });
298
+ },
299
+ };
300
+ };
301
+ ```
302
+
303
+ ### BulkActions Custom Actions
304
+
305
+ **Example 3: BulkAction with Wix API call (REQUIRES errorHandler)**
306
+ ```typescript
307
+ import { errorHandler } from '@wix/essentials';
308
+ import { CustomBulkActionsActionResolver } from '@wix/auto-patterns';
309
+
310
+ export const bulkUpdateStatus: CustomBulkActionsActionResolver = (params) => {
311
+ const { actionParams, sdk } = params;
312
+ const { selectedValues } = actionParams;
313
+
314
+ return {
315
+ label: 'Bulk Update Status',
316
+ icon: <BulkUpdateIcon />,
317
+ onClick: () => {
318
+ // ✅ CORRECT: Wix API call wrapped with errorHandler
319
+ errorHandler.withErrorHandler(
320
+ async () => {
321
+ const response = await httpClient.request(
322
+ bulkUpdateEntityStatus({
323
+ entityIds: selectedValues.map(item => item.id),
324
+ status: 'active'
325
+ })
326
+ );
327
+ return response.data;
328
+ },
329
+ {}
330
+ );
331
+ },
332
+ };
333
+ };
334
+ ```
335
+
336
+ ### CollectionPage Custom Actions
337
+
338
+ **Example 4: CollectionPage action with Wix API call (REQUIRES errorHandler)**
339
+ ```typescript
340
+ import { errorHandler } from '@wix/essentials';
341
+ import { CustomActionCollectionPageActionResolver } from '@wix/auto-patterns';
342
+
343
+ export const exportCollection: CustomActionCollectionPageActionResolver = (params) => {
344
+ const { actionParams, sdk } = params;
345
+ const { collectionId } = actionParams;
346
+
347
+ return {
348
+ label: 'Export Collection',
349
+ icon: <ExportIcon />,
350
+ onClick: () => {
351
+ // ✅ CORRECT: Wix API call wrapped with errorHandler
352
+ errorHandler.withErrorHandler(
353
+ async () => {
354
+ const response = await httpClient.request(
355
+ exportCollectionData({ collectionId })
356
+ );
357
+ return response.data;
358
+ },
359
+ {}
360
+ );
361
+ },
362
+ };
363
+ };
364
+ ```
365
+
366
+ ### EntityPage Custom Actions
367
+
368
+ **Example 5: EntityPage action with Wix API call (REQUIRES errorHandler)**
369
+ ```typescript
370
+ import { errorHandler } from '@wix/essentials';
371
+ import { CustomEntityPageMoreActionsActionResolver } from '@wix/auto-patterns';
372
+
373
+ export const sendEmail: CustomEntityPageMoreActionsActionResolver = (params) => {
374
+ const { actionParams, sdk } = params;
375
+ const { entity } = actionParams;
376
+
377
+ return {
378
+ label: 'Send Email',
379
+ icon: <EmailIcon />,
380
+ onClick: () => {
381
+ // ✅ CORRECT: Wix API call wrapped with errorHandler
382
+ errorHandler.withErrorHandler(
383
+ async () => {
384
+ const response = await httpClient.request(
385
+ sendEmailToEntity({ entityId: entity.id, email: entity.email })
386
+ );
387
+ return response.data;
388
+ },
389
+ {}
390
+ );
391
+ },
392
+ };
393
+ };
394
+ ```
395
+
396
+ ### Custom Data Sources
397
+
398
+ **Example 6: Custom Data Source with Wix API calls (REQUIRES errorHandler)**
399
+ ```typescript
400
+ import { errorHandler } from '@wix/essentials';
401
+
402
+ export const myCustomDataSource = async (collectionId: string, context: any) => {
403
+ return {
404
+ id: 'myCustomCollection',
405
+ fields: {
406
+ // ... field definitions
407
+ },
408
+ idField: 'id',
409
+ actions: {
410
+ get: async (entityId: string) => {
411
+ // ✅ CORRECT: Wix API call wrapped with errorHandler
412
+ return errorHandler.withErrorHandler(
413
+ async () => {
414
+ const response = await httpClient.request(
415
+ getDummyEntity({ dummyEntityId: entityId })
416
+ );
417
+ return response.data.dummyEntity;
418
+ },
419
+ {}
420
+ );
421
+ },
422
+ create: async (newEntity: any) => {
423
+ // ✅ CORRECT: Wix API call wrapped with errorHandler
424
+ return errorHandler.withErrorHandler(
425
+ async () => {
426
+ const response = await httpClient.request(
427
+ createDummyEntity({ dummyEntity: newEntity })
428
+ );
429
+ return response.data.dummyEntity;
430
+ },
431
+ {}
432
+ );
433
+ },
434
+ // ... other actions
435
+ },
436
+ };
437
+ };
438
+ ```
439
+
440
+ ### Actions Using SDK Methods (NO errorHandler needed)
441
+
442
+ **Example 7: Action using SDK methods (NO errorHandler needed)**
443
+ ```typescript
444
+ import { CustomActionCellActionResolver } from '@wix/auto-patterns';
445
+
446
+ export const quickUpdate: CustomActionCellActionResolver = (params) => {
447
+ const { actionParams, sdk } = params;
448
+ const { item } = actionParams;
449
+
450
+ return {
451
+ label: 'Quick Update',
452
+ icon: <QuickUpdateIcon />,
453
+ onClick: () => {
454
+ // ✅ CORRECT: SDK methods - NO errorHandler needed
455
+ const optimisticActions = sdk.getOptimisticActions(sdk.collectionId);
456
+ const schema = sdk.getSchema(sdk.collectionId);
457
+
458
+ const updatedItem = { ...item, lastUpdated: new Date() };
459
+ optimisticActions.updateOne(updatedItem, {
460
+ submit: async (items) => schema.actions.update(items[0]),
461
+ successToast: 'Item updated successfully',
462
+ errorToast: (err, {retry}) => ({
463
+ text: 'Update failed',
464
+ action: { text: 'Retry', onClick: retry }
465
+ })
466
+ });
467
+ },
468
+ };
469
+ };
470
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/auto-patterns",
3
- "version": "1.34.0",
3
+ "version": "1.35.0",
4
4
  "license": "UNLICENSED",
5
5
  "author": {
6
6
  "name": "Matvey Oklander",
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "@babel/runtime": "^7.28.4",
39
- "@wix/data": "^1.0.289",
39
+ "@wix/data": "^1.0.290",
40
40
  "@wix/wix-ui-icons-common": "^3.87.3",
41
41
  "lodash": "^4.17.21"
42
42
  },
@@ -51,14 +51,14 @@
51
51
  "@types/node": "^16.18.126",
52
52
  "@types/node-fetch": "^2.6.13",
53
53
  "@types/react": "^16.14.66",
54
- "@wix/crm": "^1.0.1021",
54
+ "@wix/crm": "^1.0.1022",
55
55
  "@wix/design-system": "^1.214.3",
56
56
  "@wix/eslint-config-yoshi": "^6.158.0",
57
57
  "@wix/fe-essentials-standalone": "^1.1380.0",
58
58
  "@wix/jest-yoshi-preset": "^6.158.0",
59
- "@wix/patterns": "^1.277.0",
59
+ "@wix/patterns": "^1.279.0",
60
60
  "@wix/sdk": "^1.16.0",
61
- "@wix/sdk-testkit": ">=0.1.7",
61
+ "@wix/sdk-testkit": ">=0.1.8",
62
62
  "@wix/wix-data-items-common": "^1.0.235",
63
63
  "@wix/wix-data-items-sdk": "^1.0.428",
64
64
  "@wix/yoshi-flow-library": "^6.158.0",
@@ -125,5 +125,5 @@
125
125
  "wallaby": {
126
126
  "autoDetect": true
127
127
  },
128
- "falconPackageHash": "3b95f950e8cf046662d2a6326593abe425912fede0ff9c0711897c1f"
128
+ "falconPackageHash": "da47af708036d7d07cc5947543173eddfa769691a73169ff7e5a65b2"
129
129
  }