@fluentcommerce/fc-connect-sdk 0.1.54 → 0.1.56
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.
- package/CHANGELOG.md +12 -0
- package/README.md +11 -0
- package/dist/cjs/clients/fluent-client.js +13 -6
- package/dist/cjs/utils/pagination-helpers.js +38 -2
- package/dist/cjs/versori/fluent-versori-client.js +11 -5
- package/dist/esm/clients/fluent-client.js +13 -6
- package/dist/esm/utils/pagination-helpers.js +38 -2
- package/dist/esm/versori/fluent-versori-client.js +11 -5
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/tsconfig.types.tsbuildinfo +1 -1
- package/docs/00-START-HERE/EXPORT-VALIDATION.md +158 -158
- package/docs/00-START-HERE/cli-analyze-source-structure-guide.md +655 -655
- package/docs/00-START-HERE/cli-documentation-index.md +202 -202
- package/docs/00-START-HERE/cli-quick-reference.md +252 -252
- package/docs/00-START-HERE/decision-tree.md +552 -552
- package/docs/00-START-HERE/getting-started.md +1070 -1070
- package/docs/00-START-HERE/mapper-quick-decision-guide.md +235 -235
- package/docs/00-START-HERE/readme.md +237 -237
- package/docs/00-START-HERE/retailerid-configuration.md +404 -404
- package/docs/00-START-HERE/sdk-philosophy.md +794 -794
- package/docs/00-START-HERE/troubleshooting-quick-reference.md +1086 -1086
- package/docs/01-TEMPLATES/faq.md +686 -686
- package/docs/01-TEMPLATES/patterns/pattern-templates-guide.md +68 -68
- package/docs/01-TEMPLATES/patterns/patterns-csv-schema-validation-and-rejection-report.md +233 -233
- package/docs/01-TEMPLATES/patterns/patterns-custom-resolvers.md +407 -407
- package/docs/01-TEMPLATES/patterns/patterns-error-handling-retry.md +511 -511
- package/docs/01-TEMPLATES/patterns/patterns-field-mapping-universal.md +701 -701
- package/docs/01-TEMPLATES/patterns/patterns-large-file-splitting.md +1430 -1430
- package/docs/01-TEMPLATES/patterns/patterns-master-data-etl.md +2399 -2399
- package/docs/01-TEMPLATES/patterns/patterns-pagination-streaming.md +447 -447
- package/docs/01-TEMPLATES/patterns/patterns-state-duplicate-prevention.md +385 -385
- package/docs/01-TEMPLATES/readme.md +957 -957
- package/docs/01-TEMPLATES/standalone/standalone-asn-inbound-processing.md +1209 -1209
- package/docs/01-TEMPLATES/standalone/standalone-graphql-query-export.md +1140 -1140
- package/docs/01-TEMPLATES/standalone/standalone-graphql-to-parquet-partitioned-s3.md +432 -432
- package/docs/01-TEMPLATES/standalone/standalone-multi-channel-inventory-sync.md +1185 -1185
- package/docs/01-TEMPLATES/standalone/standalone-multi-source-aggregation.md +1462 -1462
- package/docs/01-TEMPLATES/standalone/standalone-s3-csv-batch-api.md +1390 -1390
- package/docs/01-TEMPLATES/standalone/standalone-s3-csv-inventory-to-batch.md +330 -330
- package/docs/01-TEMPLATES/standalone/standalone-scripts-guide.md +87 -87
- package/docs/01-TEMPLATES/standalone/standalone-sftp-xml-graphql.md +1444 -1444
- package/docs/01-TEMPLATES/standalone/standalone-webhook-payload-processing.md +688 -688
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-dropship-order-routing.md +193 -193
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-graphql-parquet-extraction.md +518 -518
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-inter-location-transfers.md +2162 -2162
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-pre-order-allocation.md +2226 -2226
- package/docs/01-TEMPLATES/versori/business-examples/business-scenarios-guide.md +87 -87
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-connection-validation-pattern.md +656 -656
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-dual-workflow-connector.md +835 -835
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-guide.md +108 -108
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-kv-state-management.md +1533 -1533
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-xml-response-patterns.md +1160 -1160
- package/docs/01-TEMPLATES/versori/versori-platform-guide.md +201 -201
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-asn-purchase-order.md +1906 -1906
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-dropship-routing.md +1074 -1074
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-flash-sale-reserve.md +1395 -1395
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-generic-xml-order.md +888 -888
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-payment-gateway-integration.md +2478 -2478
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-rma-returns-comprehensive.md +2240 -2240
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-xml-order-ingestion.md +2029 -2029
- package/docs/01-TEMPLATES/versori/webhooks/webhook-templates-guide.md +140 -140
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/inventory-mapping.json +20 -20
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/products_2025-01-22.csv +11 -11
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/sample-data-guide.md +34 -34
- package/docs/01-TEMPLATES/versori/workflows/_examples/workflow-examples-guide.md +36 -36
- package/docs/01-TEMPLATES/versori/workflows/extraction/extraction-modes-guide.md +1038 -1038
- package/docs/01-TEMPLATES/versori/workflows/extraction/extraction-workflows-guide.md +138 -138
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/graphql-extraction-guide.md +63 -63
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-fulfillments-to-sftp-csv.md +2062 -2062
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-fulfillments-to-sftp-xml.md +2294 -2294
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-positions-to-s3-csv.md +2461 -2461
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-positions-to-sftp-xml.md +2529 -2529
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-quantities-to-s3-csv.md +2464 -2464
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-quantities-to-s3-json.md +1959 -1959
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-orders-to-s3-csv.md +1953 -1953
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-orders-to-sftp-xml.md +2541 -2541
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-products-to-s3-json.md +2384 -2384
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-products-to-sftp-xml.md +2445 -2445
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-s3-csv.md +2355 -2355
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-s3-json.md +2042 -2042
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-sftp-xml.md +2726 -2726
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/batch-api-guide.md +206 -206
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-cycle-count-reconciliation.md +2030 -2030
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-multi-channel-inventory-sync.md +1882 -1882
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-csv-inventory-batch.md +2827 -2827
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-json-inventory-batch.md +1952 -1952
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-xml-inventory-batch.md +3289 -3289
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-csv-inventory-batch.md +3064 -3064
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-json-inventory-batch.md +3238 -3238
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-xml-inventory-batch.md +2977 -2977
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/event-api-guide.md +321 -321
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-payload-json-order-cancel-event.md +959 -959
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-payload-xml-order-cancel-event.md +1170 -1170
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-csv-product-event.md +2312 -2312
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-json-product-event.md +2999 -2999
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-parquet-product-event.md +2836 -2836
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-xml-product-event.md +2395 -2395
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-csv-product-event.md +2295 -2295
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-json-product-event.md +2602 -2602
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-parquet-product-event.md +2589 -2589
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-xml-product-event.md +3578 -3578
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/graphql-mutations-guide.md +93 -93
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-payload-json-order-update-graphql.md +1260 -1260
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-payload-xml-order-update-graphql.md +1472 -1472
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-control-graphql.md +2417 -2417
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-location-graphql.md +2811 -2811
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-price-graphql.md +2619 -2619
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-json-location-graphql.md +2807 -2807
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-xml-location-graphql.md +2373 -2373
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-csv-control-graphql.md +2740 -2740
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-csv-location-graphql.md +2760 -2760
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-json-location-graphql.md +1710 -1710
- package/docs/01-TEMPLATES/versori/workflows/ingestion/ingestion-workflows-guide.md +136 -136
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/rubix-webhooks-guide.md +520 -520
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-fulfilment-to-sftp-xml-inline.md +1418 -1418
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-fulfilment-to-sftp-xml-universal-mapper.md +1785 -1785
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-order-attribute-update.md +824 -824
- package/docs/01-TEMPLATES/versori/workflows/workflows-overview-guide.md +646 -646
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-batch-archival.md +724 -724
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-job-tracker.md +627 -627
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-partial-batch-recovery.md +561 -561
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-quick-reference.md +367 -367
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-readme.md +407 -407
- package/docs/02-CORE-GUIDES/advanced-services/readme.md +49 -49
- package/docs/02-CORE-GUIDES/api-reference/api-reference-quick-reference.md +548 -548
- package/docs/02-CORE-GUIDES/api-reference/event-api-input-output-reference.md +702 -1171
- package/docs/02-CORE-GUIDES/api-reference/examples/client-initialization.ts +286 -286
- package/docs/02-CORE-GUIDES/api-reference/graphql-error-classification.md +337 -337
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-01-client-api.md +399 -520
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-03-authentication.md +199 -199
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-04-graphql-mapping.md +925 -925
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-05-services.md +1198 -1198
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-06-data-sources.md +1083 -1083
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-07-parsers.md +1097 -1097
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-08-pagination.md +513 -513
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-08-types.md +545 -597
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-09-error-handling.md +527 -527
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-09-webhook-validation.md +514 -514
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-10-extraction.md +557 -557
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-10-utilities.md +412 -412
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-11-cli-tools.md +423 -423
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-11-error-handling.md +716 -716
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-analyze-source-structure.md +518 -518
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-partial-responses.md +212 -212
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-testing.md +300 -300
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-13-resolver-builder.md +322 -322
- package/docs/02-CORE-GUIDES/api-reference/readme.md +279 -279
- package/docs/02-CORE-GUIDES/auto-pagination/auto-pagination-quick-reference.md +351 -351
- package/docs/02-CORE-GUIDES/auto-pagination/auto-pagination-readme.md +277 -277
- package/docs/02-CORE-GUIDES/auto-pagination/examples/auto-pagination-readme.md +178 -178
- package/docs/02-CORE-GUIDES/auto-pagination/examples/common-patterns.ts +351 -351
- package/docs/02-CORE-GUIDES/auto-pagination/examples/paginate-products.ts +384 -384
- package/docs/02-CORE-GUIDES/auto-pagination/examples/paginate-virtual-positions.ts +308 -308
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-01-foundations.md +470 -470
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-02-quick-start.md +713 -713
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-03-configuration.md +754 -754
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-04-advanced-patterns.md +732 -732
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-05-sdk-integration.md +847 -847
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-06-troubleshooting.md +359 -359
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-07-api-reference.md +462 -462
- package/docs/02-CORE-GUIDES/auto-pagination/readme.md +54 -54
- package/docs/02-CORE-GUIDES/data-sources/data-sources-file-operations-error-handling.md +1487 -1487
- package/docs/02-CORE-GUIDES/data-sources/data-sources-quick-reference.md +836 -836
- package/docs/02-CORE-GUIDES/data-sources/data-sources-readme.md +276 -276
- package/docs/02-CORE-GUIDES/data-sources/data-sources-sftp-credential-access-security.md +553 -553
- package/docs/02-CORE-GUIDES/data-sources/examples/common-patterns.ts +409 -409
- package/docs/02-CORE-GUIDES/data-sources/examples/data-sources-readme.md +178 -178
- package/docs/02-CORE-GUIDES/data-sources/examples/s3-operations.ts +308 -308
- package/docs/02-CORE-GUIDES/data-sources/examples/sftp-operations.ts +371 -371
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-01-foundations.md +735 -735
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-02-s3-operations.md +1302 -1302
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-03-sftp-operations.md +1379 -1379
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-04-file-patterns.md +941 -941
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-05-advanced-topics.md +813 -813
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-06-integration-patterns.md +486 -486
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-07-troubleshooting.md +387 -387
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-08-api-reference.md +417 -417
- package/docs/02-CORE-GUIDES/data-sources/readme.md +77 -77
- package/docs/02-CORE-GUIDES/error-handling-guide.md +936 -936
- package/docs/02-CORE-GUIDES/extraction/examples/02-core-guides-extraction-readme.md +116 -116
- package/docs/02-CORE-GUIDES/extraction/examples/common-patterns.ts +428 -428
- package/docs/02-CORE-GUIDES/extraction/examples/extract-inventory-basic.ts +187 -187
- package/docs/02-CORE-GUIDES/extraction/extraction-quick-reference.md +596 -596
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-01-foundations.md +514 -514
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-02-basic-extraction.md +823 -823
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-03-parquet-processing.md +507 -507
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-04-data-enrichment.md +546 -546
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-05-transformation.md +494 -494
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-06-export-formats.md +458 -458
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-06-performance.md +138 -138
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-07-api-reference.md +148 -148
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-07-optimization.md +692 -692
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-08-extraction-orchestrator.md +1008 -1008
- package/docs/02-CORE-GUIDES/extraction/readme.md +151 -151
- package/docs/02-CORE-GUIDES/ingestion/examples/_simple-kv-store.ts +40 -40
- package/docs/02-CORE-GUIDES/ingestion/examples/error-recovery.ts +728 -728
- package/docs/02-CORE-GUIDES/ingestion/examples/event-driven.ts +501 -501
- package/docs/02-CORE-GUIDES/ingestion/examples/local-file-ingestion.ts +88 -88
- package/docs/02-CORE-GUIDES/ingestion/examples/parquet-ingestion.ts +117 -117
- package/docs/02-CORE-GUIDES/ingestion/examples/performance-optimized.ts +647 -647
- package/docs/02-CORE-GUIDES/ingestion/examples/s3-csv-ingestion.ts +169 -169
- package/docs/02-CORE-GUIDES/ingestion/examples/sftp-csv-ingestion.ts +134 -134
- package/docs/02-CORE-GUIDES/ingestion/ingestion-quick-reference.md +546 -546
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-01-introduction.md +626 -626
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-02-quick-start.md +658 -658
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-03-data-sources.md +1052 -1052
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-04-field-mapping.md +763 -763
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-05-advanced-parsers.md +676 -676
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-06-batch-api.md +1295 -1295
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-07-api-reference.md +138 -138
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-07-state-management.md +1037 -1037
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-08-performance-optimization.md +1349 -1349
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-09-best-practices.md +1893 -1893
- package/docs/02-CORE-GUIDES/ingestion/readme.md +160 -160
- package/docs/02-CORE-GUIDES/logging-guide.md +585 -585
- package/docs/02-CORE-GUIDES/mapping/error-handling-patterns.md +401 -401
- package/docs/02-CORE-GUIDES/mapping/examples/02-core-guides-mapping-readme.md +128 -128
- package/docs/02-CORE-GUIDES/mapping/examples/common-patterns.ts +273 -273
- package/docs/02-CORE-GUIDES/mapping/examples/csv-location-ingestion.json +36 -36
- package/docs/02-CORE-GUIDES/mapping/examples/csv-mapping.ts +242 -242
- package/docs/02-CORE-GUIDES/mapping/examples/graphql-to-parquet-extraction.json +36 -36
- package/docs/02-CORE-GUIDES/mapping/examples/json-mapping.ts +213 -213
- package/docs/02-CORE-GUIDES/mapping/examples/json-product-to-mutation.json +48 -48
- package/docs/02-CORE-GUIDES/mapping/examples/xml-mapping.ts +291 -291
- package/docs/02-CORE-GUIDES/mapping/examples/xml-order-to-mutation.json +45 -45
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/graphql-mutation-mapping-quick-reference.md +463 -463
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/graphql-mutation-mapping-readme.md +227 -227
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-01-introduction.md +222 -222
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-02-quick-start.md +351 -351
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-03-schema-validation.md +569 -569
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-04-mapping-patterns.md +471 -471
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-05-configuration-reference.md +611 -611
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-06-advanced-xpath.md +148 -148
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-06-path-syntax.md +464 -464
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-07-api-reference.md +94 -94
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-07-array-handling.md +307 -307
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-08-custom-resolvers.md +544 -544
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-09-advanced-patterns.md +427 -427
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-10-hooks-and-variables.md +336 -336
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-11-error-handling.md +488 -488
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-12-arguments-vs-nodes.md +383 -383
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-13-best-practices.md +477 -477
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/readme.md +62 -62
- package/docs/02-CORE-GUIDES/mapping/mapping-format-decision-tree.md +480 -480
- package/docs/02-CORE-GUIDES/mapping/mapping-graphql-alias-batching-guide.md +820 -820
- package/docs/02-CORE-GUIDES/mapping/mapping-javascript-objects.md +2369 -2369
- package/docs/02-CORE-GUIDES/mapping/mapping-mapper-comparison-guide.md +682 -682
- package/docs/02-CORE-GUIDES/mapping/modules/02-core-guides-mapping-07-api-reference.md +1327 -1327
- package/docs/02-CORE-GUIDES/mapping/modules/02-core-guides-mapping-08-error-handling.md +1142 -1142
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-04-use-cases.md +891 -891
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-06-helpers-resolvers.md +1126 -1126
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-06-sdk-resolvers.md +199 -199
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-07-api-reference.md +1319 -1319
- package/docs/02-CORE-GUIDES/mapping/readme.md +178 -178
- package/docs/02-CORE-GUIDES/mapping/resolver-registration.md +410 -410
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/common-patterns.ts +226 -226
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/custom-resolvers.ts +227 -227
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/sdk-resolvers-usage.ts +203 -203
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-readme.md +274 -274
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-api-reference.md +679 -679
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-cookbook.md +826 -826
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-guide.md +1330 -1330
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-helpers-reference.md +1437 -1437
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-parameters-reference.md +553 -553
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-troubleshooting.md +854 -854
- package/docs/02-CORE-GUIDES/mapping/resolvers/readme.md +75 -75
- package/docs/02-CORE-GUIDES/parsers/examples/02-core-guides-parsers-readme.md +161 -161
- package/docs/02-CORE-GUIDES/parsers/examples/csv-parser-examples.ts +110 -110
- package/docs/02-CORE-GUIDES/parsers/examples/json-parser-examples.ts +33 -33
- package/docs/02-CORE-GUIDES/parsers/examples/parquet-parser-examples.ts +47 -47
- package/docs/02-CORE-GUIDES/parsers/examples/xml-parser-examples.ts +38 -38
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-01-foundations.md +355 -355
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-02-csv-parser.md +772 -772
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-03-json-parser.md +789 -789
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-04-xml-parser.md +857 -857
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-05-parquet-parser.md +603 -603
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-06-integration-patterns.md +702 -702
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-06-streaming.md +121 -121
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-07-api-reference.md +89 -89
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-07-troubleshooting.md +727 -727
- package/docs/02-CORE-GUIDES/parsers/parsers-quick-reference.md +482 -482
- package/docs/02-CORE-GUIDES/parsers/parsers-readme.md +258 -258
- package/docs/02-CORE-GUIDES/parsers/readme.md +65 -65
- package/docs/02-CORE-GUIDES/readme.md +194 -194
- package/docs/02-CORE-GUIDES/webhook-validation/examples/basic-validation.ts +108 -108
- package/docs/02-CORE-GUIDES/webhook-validation/examples/common-patterns.ts +316 -316
- package/docs/02-CORE-GUIDES/webhook-validation/examples/webhook-validation-readme.md +61 -61
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-01-foundations.md +440 -440
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-02-quick-start.md +525 -525
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-03-versori-integration.md +741 -741
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-04-platform-integration.md +629 -629
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-05-configuration.md +535 -535
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-06-error-handling.md +611 -611
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-06-troubleshooting.md +124 -124
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-07-api-reference.md +511 -511
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-08-rubix-webhooks.md +590 -590
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-09-rubix-event-vs-http-call.md +432 -432
- package/docs/02-CORE-GUIDES/webhook-validation/readme.md +239 -239
- package/docs/02-CORE-GUIDES/webhook-validation/webhook-validation-quick-reference.md +392 -392
- package/docs/03-PATTERN-GUIDES/connector-scenarios/connector-scenarios-quick-reference.md +498 -498
- package/docs/03-PATTERN-GUIDES/connector-scenarios/connector-scenarios-readme.md +313 -313
- package/docs/03-PATTERN-GUIDES/connector-scenarios/examples/common-patterns.ts +612 -612
- package/docs/03-PATTERN-GUIDES/connector-scenarios/examples/connector-scenarios-readme.md +253 -253
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-01-foundations.md +452 -452
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-02-simple-scenarios.md +681 -681
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-03-intermediate-scenarios.md +637 -637
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-04-advanced-scenarios.md +650 -650
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-05-bidirectional-sync.md +233 -233
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-06-production-patterns.md +442 -442
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-07-reference.md +445 -445
- package/docs/03-PATTERN-GUIDES/connector-scenarios/readme.md +31 -31
- package/docs/03-PATTERN-GUIDES/enterprise-integration-patterns.md +1528 -1528
- package/docs/03-PATTERN-GUIDES/error-handling/comprehensive-error-handling-guide.md +1437 -1437
- package/docs/03-PATTERN-GUIDES/error-handling/error-handling-quick-reference.md +390 -390
- package/docs/03-PATTERN-GUIDES/error-handling/examples/common-patterns.ts +438 -438
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-01-foundations.md +362 -362
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-02-error-types.md +850 -850
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-03-utf8-handling.md +456 -456
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-04-error-scenarios.md +658 -658
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-05-calling-patterns.md +671 -671
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-06-retry-strategies.md +1034 -1034
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-07-monitoring.md +653 -653
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-08-api-reference.md +847 -847
- package/docs/03-PATTERN-GUIDES/error-handling/readme.md +36 -36
- package/docs/03-PATTERN-GUIDES/examples/__tests__/readme.md +40 -40
- package/docs/03-PATTERN-GUIDES/examples/__tests__/resolver-examples.test.js +282 -282
- package/docs/03-PATTERN-GUIDES/examples/test-data/03-pattern-guides-readme.md +110 -110
- package/docs/03-PATTERN-GUIDES/examples/test-data/canonical-inventory.json +123 -123
- package/docs/03-PATTERN-GUIDES/examples/test-data/canonical-order.json +171 -171
- package/docs/03-PATTERN-GUIDES/examples/test-data/readme.md +28 -28
- package/docs/03-PATTERN-GUIDES/extraction/extraction-readme.md +15 -15
- package/docs/03-PATTERN-GUIDES/extraction/readme.md +25 -25
- package/docs/03-PATTERN-GUIDES/file-operations/examples/common-patterns.ts +407 -407
- package/docs/03-PATTERN-GUIDES/file-operations/examples/file-operations-readme.md +142 -142
- package/docs/03-PATTERN-GUIDES/file-operations/file-operations-quick-reference.md +462 -462
- package/docs/03-PATTERN-GUIDES/file-operations/file-operations-readme.md +379 -379
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-01-foundations.md +430 -430
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-02-quick-start.md +484 -484
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-03-s3-operations.md +507 -507
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-04-sftp-operations.md +963 -963
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-05-streaming-performance.md +503 -503
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-06-archive-patterns.md +386 -386
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-06-error-handling.md +117 -117
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-07-api-reference.md +78 -78
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-07-testing-troubleshooting.md +567 -567
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-08-api-reference.md +1055 -1055
- package/docs/03-PATTERN-GUIDES/file-operations/readme.md +32 -32
- package/docs/03-PATTERN-GUIDES/ingestion/ingestion-readme.md +15 -15
- package/docs/03-PATTERN-GUIDES/ingestion/readme.md +25 -25
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/batch-processing.ts +130 -130
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/common-patterns.ts +360 -360
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/delta-sync.ts +130 -130
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/integration-patterns-readme.md +100 -100
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/real-time-webhook.ts +398 -398
- package/docs/03-PATTERN-GUIDES/integration-patterns/integration-patterns-quick-reference.md +962 -962
- package/docs/03-PATTERN-GUIDES/integration-patterns/integration-patterns-readme.md +134 -134
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-01-real-time-processing.md +991 -991
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-02-batch-processing.md +1547 -1547
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-03-delta-sync.md +1108 -1108
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-04-webhook-patterns.md +1181 -1181
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-05-error-handling.md +1061 -1061
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-06-advanced-integration-services.md +1547 -1547
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-06-performance.md +109 -109
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-07-api-reference.md +34 -34
- package/docs/03-PATTERN-GUIDES/integration-patterns/readme.md +30 -30
- package/docs/03-PATTERN-GUIDES/logging-minimal-mode.md +128 -128
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/common-patterns.ts +380 -380
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/multiple-connections-readme.md +139 -139
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/parallel-root-connections.ts +149 -149
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/real-world-scenarios.ts +405 -405
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-01-foundations.md +378 -378
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-02-quick-start.md +566 -566
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-03-targeting-connections.md +659 -659
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-04-parallel-queries.md +656 -656
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-05-best-practices.md +624 -624
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-06-api-reference.md +824 -824
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-06-versori.md +119 -119
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-07-api-reference.md +87 -87
- package/docs/03-PATTERN-GUIDES/multiple-connections/multiple-connections-quick-reference.md +353 -353
- package/docs/03-PATTERN-GUIDES/multiple-connections/multiple-connections-readme.md +270 -270
- package/docs/03-PATTERN-GUIDES/multiple-connections/readme.md +30 -30
- package/docs/03-PATTERN-GUIDES/pagination/pagination-readme.md +14 -14
- package/docs/03-PATTERN-GUIDES/pagination/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/parquet/examples/common-patterns.ts +180 -180
- package/docs/03-PATTERN-GUIDES/parquet/examples/read-parquet.ts +48 -48
- package/docs/03-PATTERN-GUIDES/parquet/examples/write-parquet.ts +65 -65
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-01-introduction.md +393 -393
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-02-quick-start.md +572 -572
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-03-reading-parquet.md +525 -525
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-04-writing-parquet.md +554 -554
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-05-graphql-extraction.md +405 -405
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-06-performance.md +104 -104
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-06-s3-integration.md +511 -511
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-07-api-reference.md +90 -90
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-07-performance-optimization.md +525 -525
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-08-best-practices.md +712 -712
- package/docs/03-PATTERN-GUIDES/parquet/parquet-quick-reference.md +683 -683
- package/docs/03-PATTERN-GUIDES/parquet/parquet-readme.md +248 -248
- package/docs/03-PATTERN-GUIDES/parquet/readme.md +32 -32
- package/docs/03-PATTERN-GUIDES/parsers/parsers-readme.md +12 -12
- package/docs/03-PATTERN-GUIDES/parsers/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/readme.md +159 -159
- package/docs/03-PATTERN-GUIDES/webhooks/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/webhooks/webhooks-readme.md +8 -8
- package/docs/04-REFERENCE/architecture/architecture-01-overview.md +427 -427
- package/docs/04-REFERENCE/architecture/architecture-02-client-architecture.md +424 -424
- package/docs/04-REFERENCE/architecture/architecture-03-data-flow.md +690 -690
- package/docs/04-REFERENCE/architecture/architecture-04-service-layer.md +834 -834
- package/docs/04-REFERENCE/architecture/architecture-05-integration-architecture.md +655 -655
- package/docs/04-REFERENCE/architecture/architecture-06-state-management.md +653 -653
- package/docs/04-REFERENCE/architecture/architecture-adding-new-data-sources.md +686 -686
- package/docs/04-REFERENCE/architecture/readme.md +279 -279
- package/docs/04-REFERENCE/platforms/deno/readme.md +117 -117
- package/docs/04-REFERENCE/platforms/nodejs/readme.md +146 -146
- package/docs/04-REFERENCE/platforms/readme.md +135 -135
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-01-introduction.md +398 -398
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-02-quick-start.md +560 -560
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-03-authentication.md +757 -757
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-04-workflows.md +2476 -2476
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-05-connections.md +1167 -1167
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-06-kv-storage.md +990 -990
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-06-state-management.md +121 -121
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-07-api-reference.md +68 -68
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-07-deployment.md +731 -731
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-08-best-practices.md +1111 -1111
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-09-signature-reference.md +766 -766
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-readme.md +299 -299
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-s3-sftp-configuration-guide.md +1425 -1425
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-webhook-api-key-security.md +816 -816
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-webhook-connection-security.md +681 -681
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-workflow-task-types.md +708 -708
- package/docs/04-REFERENCE/platforms/versori/readme.md +108 -108
- package/docs/04-REFERENCE/readme.md +148 -148
- package/docs/04-REFERENCE/resolver-signature/examples/advanced-resolvers.ts +482 -482
- package/docs/04-REFERENCE/resolver-signature/examples/async-resolvers.ts +496 -496
- package/docs/04-REFERENCE/resolver-signature/examples/basic-resolvers.ts +343 -343
- package/docs/04-REFERENCE/resolver-signature/examples/resolver-signature-readme.md +188 -188
- package/docs/04-REFERENCE/resolver-signature/examples/testing-resolvers.ts +463 -463
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-01-foundations.md +286 -286
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-02-parameter-reference.md +643 -643
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-03-basic-examples.md +521 -521
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-04-advanced-patterns.md +739 -739
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-05-sdk-resolvers.md +531 -531
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-06-migration-guide.md +650 -650
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-06-testing.md +125 -125
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-07-api-reference.md +794 -794
- package/docs/04-REFERENCE/resolver-signature/readme.md +64 -64
- package/docs/04-REFERENCE/resolver-signature/resolver-signature-quick-reference.md +270 -270
- package/docs/04-REFERENCE/resolver-signature/resolver-signature-readme.md +351 -351
- package/docs/04-REFERENCE/schema/fluent-commerce-schema.json +764 -764
- package/docs/04-REFERENCE/schema/readme.md +141 -141
- package/docs/04-REFERENCE/testing/examples/04-reference-testing-readme.md +158 -158
- package/docs/04-REFERENCE/testing/examples/fluent-testing.ts +62 -62
- package/docs/04-REFERENCE/testing/examples/health-check.ts +155 -155
- package/docs/04-REFERENCE/testing/examples/integration-test.ts +119 -119
- package/docs/04-REFERENCE/testing/examples/performance-test.ts +183 -183
- package/docs/04-REFERENCE/testing/examples/s3-testing.ts +127 -127
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-01-foundations.md +267 -267
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-02-s3-testing.md +599 -599
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-03-fluent-testing.md +589 -589
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-04-integration-testing.md +699 -699
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-05-debugging.md +478 -478
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-06-cicd-integration.md +463 -463
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-06-preflight-validation.md +131 -131
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-07-best-practices.md +499 -499
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-07-coverage-ci.md +165 -165
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-08-api-reference.md +634 -634
- package/docs/04-REFERENCE/testing/readme.md +86 -86
- package/docs/04-REFERENCE/testing/testing-quick-reference.md +667 -667
- package/docs/04-REFERENCE/testing/testing-readme.md +286 -286
- package/docs/04-REFERENCE/troubleshooting/readme.md +144 -144
- package/docs/04-REFERENCE/troubleshooting/troubleshooting-deno-sftp-compatibility.md +392 -392
- package/docs/template-loading-matrix.md +242 -242
- package/package.json +5 -3
- package/docs/02-CORE-GUIDES/api-reference/cli-profile-integration.md +0 -377
|
@@ -1,716 +1,716 @@
|
|
|
1
|
-
# Module 11: Error Handling
|
|
2
|
-
|
|
3
|
-
**Level:** Intermediate to Advanced
|
|
4
|
-
**Category:** Reliability & Resilience
|
|
5
|
-
|
|
6
|
-
## Overview
|
|
7
|
-
|
|
8
|
-
Robust error handling is critical for production integrations. The SDK provides comprehensive error types, retry strategies, partial batch recovery, and job tracking to handle failures gracefully and ensure data integrity.
|
|
9
|
-
|
|
10
|
-
## Table of Contents
|
|
11
|
-
|
|
12
|
-
- [Error Types](#error-types)
|
|
13
|
-
- [Retry Strategies](#retry-strategies)
|
|
14
|
-
- [PartialBatchRecovery Service](#partialbatchrecovery-service)
|
|
15
|
-
- [JobTracker Service](#jobtracker-service)
|
|
16
|
-
- [Error Recovery Patterns](#error-recovery-patterns)
|
|
17
|
-
- [Logging and Monitoring](#logging-and-monitoring)
|
|
18
|
-
- [Common Error Scenarios](#common-error-scenarios)
|
|
19
|
-
- [Best Practices](#best-practices)
|
|
20
|
-
- [Troubleshooting](#troubleshooting)
|
|
21
|
-
- [See Also](#see-also)
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## Error Types
|
|
26
|
-
|
|
27
|
-
The SDK defines custom error classes for different failure scenarios:
|
|
28
|
-
|
|
29
|
-
### FluentAPIError
|
|
30
|
-
|
|
31
|
-
API-level errors from Fluent Commerce:
|
|
32
|
-
|
|
33
|
-
```typescript
|
|
34
|
-
import { FluentAPIError } from '@fluentcommerce/fc-connect-sdk';
|
|
35
|
-
|
|
36
|
-
try {
|
|
37
|
-
await client.graphql({ query });
|
|
38
|
-
} catch (error) {
|
|
39
|
-
if (error instanceof FluentAPIError) {
|
|
40
|
-
console.error('API Error:', {
|
|
41
|
-
statusCode: error.statusCode, // HTTP status (400, 401, 500, etc.)
|
|
42
|
-
message: error.message, // Error message
|
|
43
|
-
errors: error.errors, // GraphQL errors array
|
|
44
|
-
requestId: error.requestId // Request ID for support
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
**Common Status Codes:**
|
|
51
|
-
|
|
52
|
-
| Code | Meaning | Solution |
|
|
53
|
-
|------|---------|----------|
|
|
54
|
-
| 401 | Unauthorized | Check credentials, refresh token |
|
|
55
|
-
| 403 | Forbidden | Verify permissions/scopes |
|
|
56
|
-
| 429 | Rate Limited | Implement backoff, reduce request rate |
|
|
57
|
-
| 500 | Server Error | Retry with exponential backoff |
|
|
58
|
-
|
|
59
|
-
### AuthenticationError
|
|
60
|
-
|
|
61
|
-
OAuth2 authentication failures (401 Unauthorized):
|
|
62
|
-
|
|
63
|
-
```typescript
|
|
64
|
-
import { AuthenticationError } from '@fluentcommerce/fc-connect-sdk';
|
|
65
|
-
|
|
66
|
-
try {
|
|
67
|
-
await client.sendEvent(event, 'sync');
|
|
68
|
-
} catch (error) {
|
|
69
|
-
if (error instanceof AuthenticationError) {
|
|
70
|
-
console.error('Auth failed:', {
|
|
71
|
-
message: error.message,
|
|
72
|
-
statusCode: error.statusCode, // Always 401
|
|
73
|
-
code: error.code, // "AUTHENTICATION_ERROR"
|
|
74
|
-
details: error.details // { response: "..." }
|
|
75
|
-
});
|
|
76
|
-
// Check credentials, refresh token
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
**Note:** `FluentVersoriClient` throws `AuthenticationError` for 401 status codes (matching `FluentClient` behavior).
|
|
82
|
-
|
|
83
|
-
### GraphQLExecutionError
|
|
84
|
-
|
|
85
|
-
GraphQL query/mutation execution errors:
|
|
86
|
-
|
|
87
|
-
```typescript
|
|
88
|
-
import { GraphQLExecutionError } from '@fluentcommerce/fc-connect-sdk';
|
|
89
|
-
|
|
90
|
-
try {
|
|
91
|
-
await client.graphql({ query, variables });
|
|
92
|
-
} catch (error) {
|
|
93
|
-
if (error instanceof GraphQLExecutionError) {
|
|
94
|
-
console.error('GraphQL Error:', {
|
|
95
|
-
message: error.message,
|
|
96
|
-
graphqlErrors: error.graphqlErrors, // Array of GraphQL errors
|
|
97
|
-
query: error.query, // Original query
|
|
98
|
-
variables: error.variables // Original variables
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
// Check if validation error
|
|
102
|
-
if (error.isValidationError()) {
|
|
103
|
-
console.error('Validation failed');
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Check if auth error
|
|
107
|
-
if (error.isAuthError()) {
|
|
108
|
-
console.error('Authentication failed');
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
**Note:** Both `FluentClient` and `FluentVersoriClient` throw `GraphQLExecutionError` for GraphQL response errors (fail-fast behavior).
|
|
115
|
-
|
|
116
|
-
### ValidationError
|
|
117
|
-
|
|
118
|
-
Schema or data validation failures:
|
|
119
|
-
|
|
120
|
-
```typescript
|
|
121
|
-
import { ValidationError } from '@fluentcommerce/fc-connect-sdk';
|
|
122
|
-
|
|
123
|
-
try {
|
|
124
|
-
await mapper.map(sourceData, { validate: true });
|
|
125
|
-
} catch (error) {
|
|
126
|
-
if (error instanceof ValidationError) {
|
|
127
|
-
console.error('Validation failed:', {
|
|
128
|
-
message: error.message,
|
|
129
|
-
field: error.field, // Field that failed validation
|
|
130
|
-
value: error.value, // Invalid value
|
|
131
|
-
constraint: error.constraint // Validation rule violated
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### FluentVersoriClient Error Handling
|
|
138
|
-
|
|
139
|
-
**Important:** `FluentVersoriClient` (used in Versori platform workflows) now throws structured errors matching `FluentClient` behavior:
|
|
140
|
-
|
|
141
|
-
```typescript
|
|
142
|
-
import { createClient, FluentAPIError, AuthenticationError, GraphQLExecutionError } from '@fluentcommerce/fc-connect-sdk';
|
|
143
|
-
|
|
144
|
-
// In Versori workflow
|
|
145
|
-
export const task = schedule('task', '0 2 * * *', async (ctx) => {
|
|
146
|
-
const client = await createClient(ctx); // Returns FluentVersoriClient
|
|
147
|
-
|
|
148
|
-
try {
|
|
149
|
-
// Event API - throws FluentAPIError or AuthenticationError
|
|
150
|
-
await client.sendEvent(event, 'sync');
|
|
151
|
-
} catch (error) {
|
|
152
|
-
if (error instanceof AuthenticationError) {
|
|
153
|
-
// 401 Unauthorized
|
|
154
|
-
log.error('Auth failed', { statusCode: error.statusCode });
|
|
155
|
-
} else if (error instanceof FluentAPIError) {
|
|
156
|
-
// Other HTTP errors (400, 404, 422, 500, etc.)
|
|
157
|
-
log.error('API error', {
|
|
158
|
-
statusCode: error.statusCode,
|
|
159
|
-
response: error.details?.response
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
try {
|
|
165
|
-
// GraphQL - throws GraphQLExecutionError or FluentAPIError
|
|
166
|
-
const result = await client.graphql({ query, variables });
|
|
167
|
-
} catch (error) {
|
|
168
|
-
if (error instanceof GraphQLExecutionError) {
|
|
169
|
-
// GraphQL response errors
|
|
170
|
-
log.error('GraphQL errors', {
|
|
171
|
-
errors: error.graphqlErrors,
|
|
172
|
-
count: error.graphqlErrors.length
|
|
173
|
-
});
|
|
174
|
-
} else if (error instanceof FluentAPIError) {
|
|
175
|
-
// HTTP errors (400, 401, 500, etc.)
|
|
176
|
-
log.error('HTTP error', { statusCode: error.statusCode });
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
});
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
**Key Changes:**
|
|
183
|
-
- ✅ GraphQL errors are **thrown** (not returned in response)
|
|
184
|
-
- ✅ Event API errors throw `FluentAPIError` or `AuthenticationError`
|
|
185
|
-
- ✅ All errors have structured properties (`statusCode`, `code`, `details`)
|
|
186
|
-
- ✅ Backward compatible: generic `catch (error)` still works
|
|
187
|
-
|
|
188
|
-
### NetworkError
|
|
189
|
-
|
|
190
|
-
Connection and timeout errors:
|
|
191
|
-
|
|
192
|
-
```typescript
|
|
193
|
-
try {
|
|
194
|
-
await client.graphql({ query });
|
|
195
|
-
} catch (error) {
|
|
196
|
-
if (error.code === 'ECONNREFUSED' || error.code === 'ETIMEDOUT') {
|
|
197
|
-
console.error('Network error:', error.message);
|
|
198
|
-
// Retry with exponential backoff
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
---
|
|
204
|
-
|
|
205
|
-
## Retry Strategies
|
|
206
|
-
|
|
207
|
-
The SDK includes built-in retry logic for transient failures:
|
|
208
|
-
|
|
209
|
-
### Automatic Retries
|
|
210
|
-
|
|
211
|
-
FluentClient automatically retries failed requests:
|
|
212
|
-
|
|
213
|
-
```typescript
|
|
214
|
-
const client = await createClient({
|
|
215
|
-
config: {
|
|
216
|
-
baseUrl: process.env.FLUENT_BASE_URL,
|
|
217
|
-
clientId: process.env.FLUENT_CLIENT_ID,
|
|
218
|
-
clientSecret: process.env.FLUENT_CLIENT_SECRET,
|
|
219
|
-
retailerId: process.env.FLUENT_RETAILER_ID
|
|
220
|
-
},
|
|
221
|
-
retry: {
|
|
222
|
-
maxRetries: 3, // Retry up to 3 times
|
|
223
|
-
initialDelayMs: 1000, // Start with 1 second delay
|
|
224
|
-
maxDelayMs: 10000, // Cap at 10 seconds
|
|
225
|
-
backoffMultiplier: 2, // Double delay each retry
|
|
226
|
-
retryableStatusCodes: [408, 429, 500, 502, 503, 504] // Retry these codes
|
|
227
|
-
}
|
|
228
|
-
});
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
**Exponential Backoff:**
|
|
232
|
-
- Retry 1: Wait 1 second
|
|
233
|
-
- Retry 2: Wait 2 seconds
|
|
234
|
-
- Retry 3: Wait 4 seconds
|
|
235
|
-
- Retry 4: Wait 8 seconds (capped at maxDelayMs)
|
|
236
|
-
|
|
237
|
-
### Manual Retry Logic
|
|
238
|
-
|
|
239
|
-
For custom retry behavior:
|
|
240
|
-
|
|
241
|
-
```typescript
|
|
242
|
-
async function retryWithBackoff(fn, maxRetries = 3) {
|
|
243
|
-
let lastError;
|
|
244
|
-
|
|
245
|
-
for (let i = 0; i < maxRetries; i++) {
|
|
246
|
-
try {
|
|
247
|
-
return await fn();
|
|
248
|
-
} catch (error) {
|
|
249
|
-
lastError = error;
|
|
250
|
-
|
|
251
|
-
// Don't retry on client errors (4xx except 429)
|
|
252
|
-
if (error.statusCode >= 400 && error.statusCode < 500 && error.statusCode !== 429) {
|
|
253
|
-
throw error;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// Wait before retry (exponential backoff)
|
|
257
|
-
const delayMs = Math.min(1000 * Math.pow(2, i), 10000);
|
|
258
|
-
console.warn(`Retry ${i + 1}/${maxRetries} after ${delayMs}ms`);
|
|
259
|
-
await new Promise(resolve => setTimeout(resolve, delayMs));
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
throw lastError;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
// Usage
|
|
267
|
-
const result = await retryWithBackoff(() =>
|
|
268
|
-
client.graphql({ query })
|
|
269
|
-
);
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
---
|
|
273
|
-
|
|
274
|
-
## PartialBatchRecovery Service
|
|
275
|
-
|
|
276
|
-
Handles partial batch failures gracefully:
|
|
277
|
-
|
|
278
|
-
```typescript
|
|
279
|
-
import { createClient, PartialBatchRecovery } from '@fluentcommerce/fc-connect-sdk';
|
|
280
|
-
|
|
281
|
-
const client = await createClient({ config });
|
|
282
|
-
const recovery = new PartialBatchRecovery(client, console);
|
|
283
|
-
|
|
284
|
-
// Process batch with automatic retry of failed records
|
|
285
|
-
const result = await recovery.processBatchWithRecovery({
|
|
286
|
-
records: inventoryUpdates,
|
|
287
|
-
batchSize: 500,
|
|
288
|
-
maxRetries: 3,
|
|
289
|
-
onPartialFailure: (failedRecords, successCount) => {
|
|
290
|
-
console.log(`${successCount} succeeded, ${failedRecords.length} failed`);
|
|
291
|
-
}
|
|
292
|
-
});
|
|
293
|
-
|
|
294
|
-
console.log('Final result:', {
|
|
295
|
-
totalProcessed: result.successCount,
|
|
296
|
-
failed: result.failedRecords.length,
|
|
297
|
-
errors: result.errors
|
|
298
|
-
});
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
**Key Features:**
|
|
302
|
-
- Identifies failed records from batch response
|
|
303
|
-
- Retries only failed records (not entire batch)
|
|
304
|
-
- Tracks failure counts per record
|
|
305
|
-
- Provides detailed error reporting
|
|
306
|
-
- Prevents infinite retry loops
|
|
307
|
-
|
|
308
|
-
### Recovery Configuration
|
|
309
|
-
|
|
310
|
-
```typescript
|
|
311
|
-
await recovery.processBatchWithRecovery({
|
|
312
|
-
records: inventoryUpdates,
|
|
313
|
-
batchSize: 500, // Initial batch size
|
|
314
|
-
maxRetries: 3, // Per-record retry limit
|
|
315
|
-
retryDelayMs: 2000, // Delay between retries
|
|
316
|
-
failFast: false, // Continue on batch failure
|
|
317
|
-
onPartialFailure: (failedRecords, successCount) => {
|
|
318
|
-
// Log partial failures
|
|
319
|
-
console.log(`Partial failure: ${failedRecords.length} records failed`);
|
|
320
|
-
},
|
|
321
|
-
onRetry: (attempt, recordCount) => {
|
|
322
|
-
// Log retry attempts
|
|
323
|
-
console.log(`Retry ${attempt}: Processing ${recordCount} failed records`);
|
|
324
|
-
}
|
|
325
|
-
});
|
|
326
|
-
```
|
|
327
|
-
|
|
328
|
-
---
|
|
329
|
-
|
|
330
|
-
## JobTracker Service
|
|
331
|
-
|
|
332
|
-
Track job lifecycle and state:
|
|
333
|
-
|
|
334
|
-
```typescript
|
|
335
|
-
import { createClient, JobTracker } from '@fluentcommerce/fc-connect-sdk';
|
|
336
|
-
|
|
337
|
-
const client = await createClient({ config });
|
|
338
|
-
const tracker = new JobTracker(client, console);
|
|
339
|
-
|
|
340
|
-
// Create and track job
|
|
341
|
-
const job = await tracker.createAndTrack({
|
|
342
|
-
type: 'INVENTORY_UPDATE',
|
|
343
|
-
retailerId: process.env.FLUENT_RETAILER_ID,
|
|
344
|
-
metadata: {
|
|
345
|
-
source: 'SFTP',
|
|
346
|
-
filename: 'inventory-2025-01-15.csv'
|
|
347
|
-
}
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
console.log('Job created:', job.id);
|
|
351
|
-
|
|
352
|
-
// Send batches to job
|
|
353
|
-
for (const batch of batches) {
|
|
354
|
-
await tracker.sendBatch(job.id, batch);
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
// Poll until complete
|
|
358
|
-
const finalStatus = await tracker.pollUntilComplete(job.id, {
|
|
359
|
-
intervalMs: 5000, // Check every 5 seconds
|
|
360
|
-
timeoutMs: 300000 // Timeout after 5 minutes
|
|
361
|
-
});
|
|
362
|
-
|
|
363
|
-
console.log('Job complete:', {
|
|
364
|
-
status: finalStatus.status, // COMPLETED | FAILED | PARTIAL
|
|
365
|
-
recordsProcessed: finalStatus.recordsProcessed,
|
|
366
|
-
recordsFailed: finalStatus.recordsFailed,
|
|
367
|
-
errors: finalStatus.errors
|
|
368
|
-
});
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
**Job States:**
|
|
372
|
-
|
|
373
|
-
| State | Description | Next Actions |
|
|
374
|
-
|-------|-------------|--------------|
|
|
375
|
-
| CREATED | Job created, awaiting batches | Send batches |
|
|
376
|
-
| PROCESSING | Batches being processed | Poll for completion |
|
|
377
|
-
| COMPLETED | All records succeeded | Archive/cleanup |
|
|
378
|
-
| PARTIAL | Some records failed | Review errors, retry |
|
|
379
|
-
| FAILED | All records failed | Investigate root cause |
|
|
380
|
-
|
|
381
|
-
---
|
|
382
|
-
|
|
383
|
-
## Error Recovery Patterns
|
|
384
|
-
|
|
385
|
-
### Pattern 1: Checkpoint and Resume
|
|
386
|
-
|
|
387
|
-
```typescript
|
|
388
|
-
import { StateService } from '@fluentcommerce/fc-connect-sdk';
|
|
389
|
-
|
|
390
|
-
const stateService = new StateService(kvAdapter);
|
|
391
|
-
|
|
392
|
-
async function processFilesWithCheckpoints(files) {
|
|
393
|
-
for (const file of files) {
|
|
394
|
-
// Check if already processed
|
|
395
|
-
if (await stateService.isFileProcessed(file.name)) {
|
|
396
|
-
console.log(`Skipping ${file.name} (already processed)`);
|
|
397
|
-
continue;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
try {
|
|
401
|
-
await processFile(file);
|
|
402
|
-
|
|
403
|
-
// Mark successful
|
|
404
|
-
await stateService.markFileProcessed(file.name, {
|
|
405
|
-
processedAt: new Date().toISOString(),
|
|
406
|
-
recordCount: file.recordCount
|
|
407
|
-
});
|
|
408
|
-
} catch (error) {
|
|
409
|
-
console.error(`Failed to process ${file.name}:`, error);
|
|
410
|
-
|
|
411
|
-
// Mark failed with retry count
|
|
412
|
-
await stateService.markFileFailed(file.name, {
|
|
413
|
-
error: error.message,
|
|
414
|
-
retryCount: (await stateService.getRetryCount(file.name)) + 1
|
|
415
|
-
});
|
|
416
|
-
|
|
417
|
-
// Skip if max retries exceeded
|
|
418
|
-
if (await stateService.getRetryCount(file.name) >= 3) {
|
|
419
|
-
console.error(`Max retries exceeded for ${file.name}`);
|
|
420
|
-
continue;
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
// Will retry on next run
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
```
|
|
428
|
-
|
|
429
|
-
### Pattern 2: Dead Letter Queue
|
|
430
|
-
|
|
431
|
-
```typescript
|
|
432
|
-
const deadLetterQueue = [];
|
|
433
|
-
|
|
434
|
-
async function processWithDLQ(records) {
|
|
435
|
-
for (const record of records) {
|
|
436
|
-
try {
|
|
437
|
-
await processRecord(record);
|
|
438
|
-
} catch (error) {
|
|
439
|
-
console.error(`Record failed:`, record.ref, error.message);
|
|
440
|
-
|
|
441
|
-
// Add to DLQ after max retries
|
|
442
|
-
if (record.retryCount >= 3) {
|
|
443
|
-
deadLetterQueue.push({
|
|
444
|
-
record,
|
|
445
|
-
error: error.message,
|
|
446
|
-
timestamp: new Date().toISOString()
|
|
447
|
-
});
|
|
448
|
-
} else {
|
|
449
|
-
// Retry later
|
|
450
|
-
record.retryCount = (record.retryCount || 0) + 1;
|
|
451
|
-
await queueForRetry(record);
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
// Export DLQ for manual review
|
|
457
|
-
if (deadLetterQueue.length > 0) {
|
|
458
|
-
await exportDLQ(deadLetterQueue);
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
### Pattern 3: Circuit Breaker
|
|
464
|
-
|
|
465
|
-
```typescript
|
|
466
|
-
class CircuitBreaker {
|
|
467
|
-
constructor(threshold = 5, resetTimeMs = 60000) {
|
|
468
|
-
this.failureCount = 0;
|
|
469
|
-
this.threshold = threshold;
|
|
470
|
-
this.resetTimeMs = resetTimeMs;
|
|
471
|
-
this.state = 'CLOSED'; // CLOSED, OPEN, HALF_OPEN
|
|
472
|
-
this.lastFailureTime = null;
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
async execute(fn) {
|
|
476
|
-
if (this.state === 'OPEN') {
|
|
477
|
-
// Check if reset time has passed
|
|
478
|
-
if (Date.now() - this.lastFailureTime > this.resetTimeMs) {
|
|
479
|
-
this.state = 'HALF_OPEN';
|
|
480
|
-
} else {
|
|
481
|
-
throw new Error('Circuit breaker is OPEN');
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
try {
|
|
486
|
-
const result = await fn();
|
|
487
|
-
|
|
488
|
-
// Reset on success
|
|
489
|
-
if (this.state === 'HALF_OPEN') {
|
|
490
|
-
this.state = 'CLOSED';
|
|
491
|
-
this.failureCount = 0;
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
return result;
|
|
495
|
-
} catch (error) {
|
|
496
|
-
this.failureCount++;
|
|
497
|
-
this.lastFailureTime = Date.now();
|
|
498
|
-
|
|
499
|
-
if (this.failureCount >= this.threshold) {
|
|
500
|
-
this.state = 'OPEN';
|
|
501
|
-
console.warn('Circuit breaker opened');
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
throw error;
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
// Usage
|
|
510
|
-
const breaker = new CircuitBreaker(5, 60000);
|
|
511
|
-
|
|
512
|
-
await breaker.execute(() => client.graphql({ query }));
|
|
513
|
-
```
|
|
514
|
-
|
|
515
|
-
---
|
|
516
|
-
|
|
517
|
-
## Logging and Monitoring
|
|
518
|
-
|
|
519
|
-
### Structured Logging
|
|
520
|
-
|
|
521
|
-
```typescript
|
|
522
|
-
import { LoggingService } from '@fluentcommerce/fc-connect-sdk';
|
|
523
|
-
|
|
524
|
-
const log = new LoggingService('inventory-sync');
|
|
525
|
-
|
|
526
|
-
try {
|
|
527
|
-
await processInventory();
|
|
528
|
-
log.info('Inventory sync complete', {
|
|
529
|
-
recordCount: 1000,
|
|
530
|
-
duration: 5000
|
|
531
|
-
});
|
|
532
|
-
} catch (error) {
|
|
533
|
-
log.error('Inventory sync failed', {
|
|
534
|
-
error: error.message,
|
|
535
|
-
stack: error.stack,
|
|
536
|
-
context: {
|
|
537
|
-
filename: 'inventory.csv',
|
|
538
|
-
recordCount: 1000
|
|
539
|
-
}
|
|
540
|
-
});
|
|
541
|
-
}
|
|
542
|
-
```
|
|
543
|
-
|
|
544
|
-
### Error Metrics
|
|
545
|
-
|
|
546
|
-
```typescript
|
|
547
|
-
const errorMetrics = {
|
|
548
|
-
totalErrors: 0,
|
|
549
|
-
errorsByType: {},
|
|
550
|
-
errorsByStatus: {}
|
|
551
|
-
};
|
|
552
|
-
|
|
553
|
-
try {
|
|
554
|
-
await client.graphql({ query });
|
|
555
|
-
} catch (error) {
|
|
556
|
-
errorMetrics.totalErrors++;
|
|
557
|
-
|
|
558
|
-
if (error instanceof FluentAPIError) {
|
|
559
|
-
errorMetrics.errorsByStatus[error.statusCode] =
|
|
560
|
-
(errorMetrics.errorsByStatus[error.statusCode] || 0) + 1;
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
errorMetrics.errorsByType[error.constructor.name] =
|
|
564
|
-
(errorMetrics.errorsByType[error.constructor.name] || 0) + 1;
|
|
565
|
-
|
|
566
|
-
throw error;
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
// Report metrics
|
|
570
|
-
console.log('Error metrics:', errorMetrics);
|
|
571
|
-
```
|
|
572
|
-
|
|
573
|
-
---
|
|
574
|
-
|
|
575
|
-
## Common Error Scenarios
|
|
576
|
-
|
|
577
|
-
### Scenario 1: Transient Network Errors
|
|
578
|
-
|
|
579
|
-
**Symptom:** Intermittent `ECONNRESET` or `ETIMEDOUT` errors
|
|
580
|
-
|
|
581
|
-
**Solution:** Automatic retries with exponential backoff
|
|
582
|
-
|
|
583
|
-
### Scenario 2: Rate Limiting (429)
|
|
584
|
-
|
|
585
|
-
**Symptom:** "Too Many Requests" errors
|
|
586
|
-
|
|
587
|
-
**Solution:** Implement delays between requests
|
|
588
|
-
```typescript
|
|
589
|
-
pagination: {
|
|
590
|
-
pageSize: 100,
|
|
591
|
-
delayMs: 1000 // 1 second delay
|
|
592
|
-
}
|
|
593
|
-
```
|
|
594
|
-
|
|
595
|
-
### Scenario 3: Authentication Token Expiry
|
|
596
|
-
|
|
597
|
-
**Symptom:** 401 errors mid-process
|
|
598
|
-
|
|
599
|
-
**Solution:** FluentClient automatically refreshes tokens
|
|
600
|
-
|
|
601
|
-
### Scenario 4: Partial Batch Failures
|
|
602
|
-
|
|
603
|
-
**Symptom:** Some records succeed, others fail
|
|
604
|
-
|
|
605
|
-
**Solution:** Use PartialBatchRecovery service
|
|
606
|
-
|
|
607
|
-
### Scenario 5: Job Timeouts
|
|
608
|
-
|
|
609
|
-
**Symptom:** Job stuck in PROCESSING state
|
|
610
|
-
|
|
611
|
-
**Solution:** Implement timeout with JobTracker
|
|
612
|
-
```typescript
|
|
613
|
-
const status = await tracker.pollUntilComplete(jobId, {
|
|
614
|
-
timeoutMs: 300000 // 5-minute timeout
|
|
615
|
-
});
|
|
616
|
-
```
|
|
617
|
-
|
|
618
|
-
---
|
|
619
|
-
|
|
620
|
-
## Best Practices
|
|
621
|
-
|
|
622
|
-
1. **Always Handle Errors**
|
|
623
|
-
```typescript
|
|
624
|
-
try {
|
|
625
|
-
await riskyOperation();
|
|
626
|
-
} catch (error) {
|
|
627
|
-
log.error('Operation failed', error);
|
|
628
|
-
// Handle gracefully
|
|
629
|
-
}
|
|
630
|
-
```
|
|
631
|
-
|
|
632
|
-
2. **Use Specific Error Types**
|
|
633
|
-
```typescript
|
|
634
|
-
if (error instanceof AuthenticationError) {
|
|
635
|
-
// Re-authenticate
|
|
636
|
-
} else if (error instanceof ValidationError) {
|
|
637
|
-
// Fix data
|
|
638
|
-
}
|
|
639
|
-
```
|
|
640
|
-
|
|
641
|
-
3. **Implement Retries for Transient Errors**
|
|
642
|
-
```typescript
|
|
643
|
-
retry: {
|
|
644
|
-
maxRetries: 3,
|
|
645
|
-
retryableStatusCodes: [408, 429, 500, 502, 503, 504]
|
|
646
|
-
}
|
|
647
|
-
```
|
|
648
|
-
|
|
649
|
-
4. **Track Failed Records**
|
|
650
|
-
```typescript
|
|
651
|
-
const failed = [];
|
|
652
|
-
for (const record of records) {
|
|
653
|
-
try {
|
|
654
|
-
await process(record);
|
|
655
|
-
} catch (error) {
|
|
656
|
-
failed.push({ record, error });
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
// Export failed records for review
|
|
660
|
-
```
|
|
661
|
-
|
|
662
|
-
5. **Set Appropriate Timeouts**
|
|
663
|
-
```typescript
|
|
664
|
-
const controller = new AbortController();
|
|
665
|
-
setTimeout(() => controller.abort(), 30000);
|
|
666
|
-
await client.graphql({ query, signal: controller.signal });
|
|
667
|
-
```
|
|
668
|
-
|
|
669
|
-
---
|
|
670
|
-
|
|
671
|
-
## Troubleshooting
|
|
672
|
-
|
|
673
|
-
### Debug Mode
|
|
674
|
-
|
|
675
|
-
Enable verbose logging:
|
|
676
|
-
```typescript
|
|
677
|
-
const log = new LoggingService('connector', { level: 'debug' });
|
|
678
|
-
```
|
|
679
|
-
|
|
680
|
-
### Error Stack Traces
|
|
681
|
-
|
|
682
|
-
Preserve full stack traces:
|
|
683
|
-
```typescript
|
|
684
|
-
try {
|
|
685
|
-
await operation();
|
|
686
|
-
} catch (error) {
|
|
687
|
-
console.error('Full error:', {
|
|
688
|
-
message: error.message,
|
|
689
|
-
stack: error.stack,
|
|
690
|
-
cause: error.cause
|
|
691
|
-
});
|
|
692
|
-
throw error;
|
|
693
|
-
}
|
|
694
|
-
```
|
|
695
|
-
|
|
696
|
-
---
|
|
697
|
-
|
|
698
|
-
## See Also
|
|
699
|
-
|
|
700
|
-
**Related Modules:**
|
|
701
|
-
- [Module 05: Services](./api-reference-05-services.md) - PartialBatchRecovery, JobTracker
|
|
702
|
-
- [Module 03: Authentication](./api-reference-03-authentication.md) - Token refresh handling
|
|
703
|
-
|
|
704
|
-
**Complete Guides:**
|
|
705
|
-
- [Error Handling Guide](../../../03-PATTERN-GUIDES/error-handling/error-handling-readme.md) - Comprehensive error patterns
|
|
706
|
-
- [Batch Processing](../../ingestion/modules/02-core-guides-ingestion-06-batch-api.md) - Batch error recovery
|
|
707
|
-
|
|
708
|
-
**Templates:**
|
|
709
|
-
- [Error Handling Patterns](../../../01-TEMPLATES/patterns/error-handling-retry.md)
|
|
710
|
-
|
|
711
|
-
---
|
|
712
|
-
|
|
713
|
-
**Navigation:**
|
|
714
|
-
- [Back to Module List](./readme.md)
|
|
715
|
-
- [Previous: Module 10 - Extraction](./api-reference-10-extraction.md)
|
|
716
|
-
- [Next: Module 12 - Testing](./api-reference-12-testing.md)
|
|
1
|
+
# Module 11: Error Handling
|
|
2
|
+
|
|
3
|
+
**Level:** Intermediate to Advanced
|
|
4
|
+
**Category:** Reliability & Resilience
|
|
5
|
+
|
|
6
|
+
## Overview
|
|
7
|
+
|
|
8
|
+
Robust error handling is critical for production integrations. The SDK provides comprehensive error types, retry strategies, partial batch recovery, and job tracking to handle failures gracefully and ensure data integrity.
|
|
9
|
+
|
|
10
|
+
## Table of Contents
|
|
11
|
+
|
|
12
|
+
- [Error Types](#error-types)
|
|
13
|
+
- [Retry Strategies](#retry-strategies)
|
|
14
|
+
- [PartialBatchRecovery Service](#partialbatchrecovery-service)
|
|
15
|
+
- [JobTracker Service](#jobtracker-service)
|
|
16
|
+
- [Error Recovery Patterns](#error-recovery-patterns)
|
|
17
|
+
- [Logging and Monitoring](#logging-and-monitoring)
|
|
18
|
+
- [Common Error Scenarios](#common-error-scenarios)
|
|
19
|
+
- [Best Practices](#best-practices)
|
|
20
|
+
- [Troubleshooting](#troubleshooting)
|
|
21
|
+
- [See Also](#see-also)
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Error Types
|
|
26
|
+
|
|
27
|
+
The SDK defines custom error classes for different failure scenarios:
|
|
28
|
+
|
|
29
|
+
### FluentAPIError
|
|
30
|
+
|
|
31
|
+
API-level errors from Fluent Commerce:
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import { FluentAPIError } from '@fluentcommerce/fc-connect-sdk';
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
await client.graphql({ query });
|
|
38
|
+
} catch (error) {
|
|
39
|
+
if (error instanceof FluentAPIError) {
|
|
40
|
+
console.error('API Error:', {
|
|
41
|
+
statusCode: error.statusCode, // HTTP status (400, 401, 500, etc.)
|
|
42
|
+
message: error.message, // Error message
|
|
43
|
+
errors: error.errors, // GraphQL errors array
|
|
44
|
+
requestId: error.requestId // Request ID for support
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**Common Status Codes:**
|
|
51
|
+
|
|
52
|
+
| Code | Meaning | Solution |
|
|
53
|
+
|------|---------|----------|
|
|
54
|
+
| 401 | Unauthorized | Check credentials, refresh token |
|
|
55
|
+
| 403 | Forbidden | Verify permissions/scopes |
|
|
56
|
+
| 429 | Rate Limited | Implement backoff, reduce request rate |
|
|
57
|
+
| 500 | Server Error | Retry with exponential backoff |
|
|
58
|
+
|
|
59
|
+
### AuthenticationError
|
|
60
|
+
|
|
61
|
+
OAuth2 authentication failures (401 Unauthorized):
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { AuthenticationError } from '@fluentcommerce/fc-connect-sdk';
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
await client.sendEvent(event, 'sync');
|
|
68
|
+
} catch (error) {
|
|
69
|
+
if (error instanceof AuthenticationError) {
|
|
70
|
+
console.error('Auth failed:', {
|
|
71
|
+
message: error.message,
|
|
72
|
+
statusCode: error.statusCode, // Always 401
|
|
73
|
+
code: error.code, // "AUTHENTICATION_ERROR"
|
|
74
|
+
details: error.details // { response: "..." }
|
|
75
|
+
});
|
|
76
|
+
// Check credentials, refresh token
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Note:** `FluentVersoriClient` throws `AuthenticationError` for 401 status codes (matching `FluentClient` behavior).
|
|
82
|
+
|
|
83
|
+
### GraphQLExecutionError
|
|
84
|
+
|
|
85
|
+
GraphQL query/mutation execution errors:
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import { GraphQLExecutionError } from '@fluentcommerce/fc-connect-sdk';
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
await client.graphql({ query, variables });
|
|
92
|
+
} catch (error) {
|
|
93
|
+
if (error instanceof GraphQLExecutionError) {
|
|
94
|
+
console.error('GraphQL Error:', {
|
|
95
|
+
message: error.message,
|
|
96
|
+
graphqlErrors: error.graphqlErrors, // Array of GraphQL errors
|
|
97
|
+
query: error.query, // Original query
|
|
98
|
+
variables: error.variables // Original variables
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// Check if validation error
|
|
102
|
+
if (error.isValidationError()) {
|
|
103
|
+
console.error('Validation failed');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Check if auth error
|
|
107
|
+
if (error.isAuthError()) {
|
|
108
|
+
console.error('Authentication failed');
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Note:** Both `FluentClient` and `FluentVersoriClient` throw `GraphQLExecutionError` for GraphQL response errors (fail-fast behavior).
|
|
115
|
+
|
|
116
|
+
### ValidationError
|
|
117
|
+
|
|
118
|
+
Schema or data validation failures:
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
import { ValidationError } from '@fluentcommerce/fc-connect-sdk';
|
|
122
|
+
|
|
123
|
+
try {
|
|
124
|
+
await mapper.map(sourceData, { validate: true });
|
|
125
|
+
} catch (error) {
|
|
126
|
+
if (error instanceof ValidationError) {
|
|
127
|
+
console.error('Validation failed:', {
|
|
128
|
+
message: error.message,
|
|
129
|
+
field: error.field, // Field that failed validation
|
|
130
|
+
value: error.value, // Invalid value
|
|
131
|
+
constraint: error.constraint // Validation rule violated
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### FluentVersoriClient Error Handling
|
|
138
|
+
|
|
139
|
+
**Important:** `FluentVersoriClient` (used in Versori platform workflows) now throws structured errors matching `FluentClient` behavior:
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
import { createClient, FluentAPIError, AuthenticationError, GraphQLExecutionError } from '@fluentcommerce/fc-connect-sdk';
|
|
143
|
+
|
|
144
|
+
// In Versori workflow
|
|
145
|
+
export const task = schedule('task', '0 2 * * *', async (ctx) => {
|
|
146
|
+
const client = await createClient(ctx); // Returns FluentVersoriClient
|
|
147
|
+
|
|
148
|
+
try {
|
|
149
|
+
// Event API - throws FluentAPIError or AuthenticationError
|
|
150
|
+
await client.sendEvent(event, 'sync');
|
|
151
|
+
} catch (error) {
|
|
152
|
+
if (error instanceof AuthenticationError) {
|
|
153
|
+
// 401 Unauthorized
|
|
154
|
+
log.error('Auth failed', { statusCode: error.statusCode });
|
|
155
|
+
} else if (error instanceof FluentAPIError) {
|
|
156
|
+
// Other HTTP errors (400, 404, 422, 500, etc.)
|
|
157
|
+
log.error('API error', {
|
|
158
|
+
statusCode: error.statusCode,
|
|
159
|
+
response: error.details?.response
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
try {
|
|
165
|
+
// GraphQL - throws GraphQLExecutionError or FluentAPIError
|
|
166
|
+
const result = await client.graphql({ query, variables });
|
|
167
|
+
} catch (error) {
|
|
168
|
+
if (error instanceof GraphQLExecutionError) {
|
|
169
|
+
// GraphQL response errors
|
|
170
|
+
log.error('GraphQL errors', {
|
|
171
|
+
errors: error.graphqlErrors,
|
|
172
|
+
count: error.graphqlErrors.length
|
|
173
|
+
});
|
|
174
|
+
} else if (error instanceof FluentAPIError) {
|
|
175
|
+
// HTTP errors (400, 401, 500, etc.)
|
|
176
|
+
log.error('HTTP error', { statusCode: error.statusCode });
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
**Key Changes:**
|
|
183
|
+
- ✅ GraphQL errors are **thrown** (not returned in response)
|
|
184
|
+
- ✅ Event API errors throw `FluentAPIError` or `AuthenticationError`
|
|
185
|
+
- ✅ All errors have structured properties (`statusCode`, `code`, `details`)
|
|
186
|
+
- ✅ Backward compatible: generic `catch (error)` still works
|
|
187
|
+
|
|
188
|
+
### NetworkError
|
|
189
|
+
|
|
190
|
+
Connection and timeout errors:
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
try {
|
|
194
|
+
await client.graphql({ query });
|
|
195
|
+
} catch (error) {
|
|
196
|
+
if (error.code === 'ECONNREFUSED' || error.code === 'ETIMEDOUT') {
|
|
197
|
+
console.error('Network error:', error.message);
|
|
198
|
+
// Retry with exponential backoff
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## Retry Strategies
|
|
206
|
+
|
|
207
|
+
The SDK includes built-in retry logic for transient failures:
|
|
208
|
+
|
|
209
|
+
### Automatic Retries
|
|
210
|
+
|
|
211
|
+
FluentClient automatically retries failed requests:
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
const client = await createClient({
|
|
215
|
+
config: {
|
|
216
|
+
baseUrl: process.env.FLUENT_BASE_URL,
|
|
217
|
+
clientId: process.env.FLUENT_CLIENT_ID,
|
|
218
|
+
clientSecret: process.env.FLUENT_CLIENT_SECRET,
|
|
219
|
+
retailerId: process.env.FLUENT_RETAILER_ID
|
|
220
|
+
},
|
|
221
|
+
retry: {
|
|
222
|
+
maxRetries: 3, // Retry up to 3 times
|
|
223
|
+
initialDelayMs: 1000, // Start with 1 second delay
|
|
224
|
+
maxDelayMs: 10000, // Cap at 10 seconds
|
|
225
|
+
backoffMultiplier: 2, // Double delay each retry
|
|
226
|
+
retryableStatusCodes: [408, 429, 500, 502, 503, 504] // Retry these codes
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**Exponential Backoff:**
|
|
232
|
+
- Retry 1: Wait 1 second
|
|
233
|
+
- Retry 2: Wait 2 seconds
|
|
234
|
+
- Retry 3: Wait 4 seconds
|
|
235
|
+
- Retry 4: Wait 8 seconds (capped at maxDelayMs)
|
|
236
|
+
|
|
237
|
+
### Manual Retry Logic
|
|
238
|
+
|
|
239
|
+
For custom retry behavior:
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
async function retryWithBackoff(fn, maxRetries = 3) {
|
|
243
|
+
let lastError;
|
|
244
|
+
|
|
245
|
+
for (let i = 0; i < maxRetries; i++) {
|
|
246
|
+
try {
|
|
247
|
+
return await fn();
|
|
248
|
+
} catch (error) {
|
|
249
|
+
lastError = error;
|
|
250
|
+
|
|
251
|
+
// Don't retry on client errors (4xx except 429)
|
|
252
|
+
if (error.statusCode >= 400 && error.statusCode < 500 && error.statusCode !== 429) {
|
|
253
|
+
throw error;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Wait before retry (exponential backoff)
|
|
257
|
+
const delayMs = Math.min(1000 * Math.pow(2, i), 10000);
|
|
258
|
+
console.warn(`Retry ${i + 1}/${maxRetries} after ${delayMs}ms`);
|
|
259
|
+
await new Promise(resolve => setTimeout(resolve, delayMs));
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
throw lastError;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Usage
|
|
267
|
+
const result = await retryWithBackoff(() =>
|
|
268
|
+
client.graphql({ query })
|
|
269
|
+
);
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## PartialBatchRecovery Service
|
|
275
|
+
|
|
276
|
+
Handles partial batch failures gracefully:
|
|
277
|
+
|
|
278
|
+
```typescript
|
|
279
|
+
import { createClient, PartialBatchRecovery } from '@fluentcommerce/fc-connect-sdk';
|
|
280
|
+
|
|
281
|
+
const client = await createClient({ config });
|
|
282
|
+
const recovery = new PartialBatchRecovery(client, console);
|
|
283
|
+
|
|
284
|
+
// Process batch with automatic retry of failed records
|
|
285
|
+
const result = await recovery.processBatchWithRecovery({
|
|
286
|
+
records: inventoryUpdates,
|
|
287
|
+
batchSize: 500,
|
|
288
|
+
maxRetries: 3,
|
|
289
|
+
onPartialFailure: (failedRecords, successCount) => {
|
|
290
|
+
console.log(`${successCount} succeeded, ${failedRecords.length} failed`);
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
console.log('Final result:', {
|
|
295
|
+
totalProcessed: result.successCount,
|
|
296
|
+
failed: result.failedRecords.length,
|
|
297
|
+
errors: result.errors
|
|
298
|
+
});
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
**Key Features:**
|
|
302
|
+
- Identifies failed records from batch response
|
|
303
|
+
- Retries only failed records (not entire batch)
|
|
304
|
+
- Tracks failure counts per record
|
|
305
|
+
- Provides detailed error reporting
|
|
306
|
+
- Prevents infinite retry loops
|
|
307
|
+
|
|
308
|
+
### Recovery Configuration
|
|
309
|
+
|
|
310
|
+
```typescript
|
|
311
|
+
await recovery.processBatchWithRecovery({
|
|
312
|
+
records: inventoryUpdates,
|
|
313
|
+
batchSize: 500, // Initial batch size
|
|
314
|
+
maxRetries: 3, // Per-record retry limit
|
|
315
|
+
retryDelayMs: 2000, // Delay between retries
|
|
316
|
+
failFast: false, // Continue on batch failure
|
|
317
|
+
onPartialFailure: (failedRecords, successCount) => {
|
|
318
|
+
// Log partial failures
|
|
319
|
+
console.log(`Partial failure: ${failedRecords.length} records failed`);
|
|
320
|
+
},
|
|
321
|
+
onRetry: (attempt, recordCount) => {
|
|
322
|
+
// Log retry attempts
|
|
323
|
+
console.log(`Retry ${attempt}: Processing ${recordCount} failed records`);
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
## JobTracker Service
|
|
331
|
+
|
|
332
|
+
Track job lifecycle and state:
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
import { createClient, JobTracker } from '@fluentcommerce/fc-connect-sdk';
|
|
336
|
+
|
|
337
|
+
const client = await createClient({ config });
|
|
338
|
+
const tracker = new JobTracker(client, console);
|
|
339
|
+
|
|
340
|
+
// Create and track job
|
|
341
|
+
const job = await tracker.createAndTrack({
|
|
342
|
+
type: 'INVENTORY_UPDATE',
|
|
343
|
+
retailerId: process.env.FLUENT_RETAILER_ID,
|
|
344
|
+
metadata: {
|
|
345
|
+
source: 'SFTP',
|
|
346
|
+
filename: 'inventory-2025-01-15.csv'
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
console.log('Job created:', job.id);
|
|
351
|
+
|
|
352
|
+
// Send batches to job
|
|
353
|
+
for (const batch of batches) {
|
|
354
|
+
await tracker.sendBatch(job.id, batch);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// Poll until complete
|
|
358
|
+
const finalStatus = await tracker.pollUntilComplete(job.id, {
|
|
359
|
+
intervalMs: 5000, // Check every 5 seconds
|
|
360
|
+
timeoutMs: 300000 // Timeout after 5 minutes
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
console.log('Job complete:', {
|
|
364
|
+
status: finalStatus.status, // COMPLETED | FAILED | PARTIAL
|
|
365
|
+
recordsProcessed: finalStatus.recordsProcessed,
|
|
366
|
+
recordsFailed: finalStatus.recordsFailed,
|
|
367
|
+
errors: finalStatus.errors
|
|
368
|
+
});
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
**Job States:**
|
|
372
|
+
|
|
373
|
+
| State | Description | Next Actions |
|
|
374
|
+
|-------|-------------|--------------|
|
|
375
|
+
| CREATED | Job created, awaiting batches | Send batches |
|
|
376
|
+
| PROCESSING | Batches being processed | Poll for completion |
|
|
377
|
+
| COMPLETED | All records succeeded | Archive/cleanup |
|
|
378
|
+
| PARTIAL | Some records failed | Review errors, retry |
|
|
379
|
+
| FAILED | All records failed | Investigate root cause |
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
## Error Recovery Patterns
|
|
384
|
+
|
|
385
|
+
### Pattern 1: Checkpoint and Resume
|
|
386
|
+
|
|
387
|
+
```typescript
|
|
388
|
+
import { StateService } from '@fluentcommerce/fc-connect-sdk';
|
|
389
|
+
|
|
390
|
+
const stateService = new StateService(kvAdapter);
|
|
391
|
+
|
|
392
|
+
async function processFilesWithCheckpoints(files) {
|
|
393
|
+
for (const file of files) {
|
|
394
|
+
// Check if already processed
|
|
395
|
+
if (await stateService.isFileProcessed(file.name)) {
|
|
396
|
+
console.log(`Skipping ${file.name} (already processed)`);
|
|
397
|
+
continue;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
try {
|
|
401
|
+
await processFile(file);
|
|
402
|
+
|
|
403
|
+
// Mark successful
|
|
404
|
+
await stateService.markFileProcessed(file.name, {
|
|
405
|
+
processedAt: new Date().toISOString(),
|
|
406
|
+
recordCount: file.recordCount
|
|
407
|
+
});
|
|
408
|
+
} catch (error) {
|
|
409
|
+
console.error(`Failed to process ${file.name}:`, error);
|
|
410
|
+
|
|
411
|
+
// Mark failed with retry count
|
|
412
|
+
await stateService.markFileFailed(file.name, {
|
|
413
|
+
error: error.message,
|
|
414
|
+
retryCount: (await stateService.getRetryCount(file.name)) + 1
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
// Skip if max retries exceeded
|
|
418
|
+
if (await stateService.getRetryCount(file.name) >= 3) {
|
|
419
|
+
console.error(`Max retries exceeded for ${file.name}`);
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// Will retry on next run
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
### Pattern 2: Dead Letter Queue
|
|
430
|
+
|
|
431
|
+
```typescript
|
|
432
|
+
const deadLetterQueue = [];
|
|
433
|
+
|
|
434
|
+
async function processWithDLQ(records) {
|
|
435
|
+
for (const record of records) {
|
|
436
|
+
try {
|
|
437
|
+
await processRecord(record);
|
|
438
|
+
} catch (error) {
|
|
439
|
+
console.error(`Record failed:`, record.ref, error.message);
|
|
440
|
+
|
|
441
|
+
// Add to DLQ after max retries
|
|
442
|
+
if (record.retryCount >= 3) {
|
|
443
|
+
deadLetterQueue.push({
|
|
444
|
+
record,
|
|
445
|
+
error: error.message,
|
|
446
|
+
timestamp: new Date().toISOString()
|
|
447
|
+
});
|
|
448
|
+
} else {
|
|
449
|
+
// Retry later
|
|
450
|
+
record.retryCount = (record.retryCount || 0) + 1;
|
|
451
|
+
await queueForRetry(record);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// Export DLQ for manual review
|
|
457
|
+
if (deadLetterQueue.length > 0) {
|
|
458
|
+
await exportDLQ(deadLetterQueue);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
### Pattern 3: Circuit Breaker
|
|
464
|
+
|
|
465
|
+
```typescript
|
|
466
|
+
class CircuitBreaker {
|
|
467
|
+
constructor(threshold = 5, resetTimeMs = 60000) {
|
|
468
|
+
this.failureCount = 0;
|
|
469
|
+
this.threshold = threshold;
|
|
470
|
+
this.resetTimeMs = resetTimeMs;
|
|
471
|
+
this.state = 'CLOSED'; // CLOSED, OPEN, HALF_OPEN
|
|
472
|
+
this.lastFailureTime = null;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
async execute(fn) {
|
|
476
|
+
if (this.state === 'OPEN') {
|
|
477
|
+
// Check if reset time has passed
|
|
478
|
+
if (Date.now() - this.lastFailureTime > this.resetTimeMs) {
|
|
479
|
+
this.state = 'HALF_OPEN';
|
|
480
|
+
} else {
|
|
481
|
+
throw new Error('Circuit breaker is OPEN');
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
try {
|
|
486
|
+
const result = await fn();
|
|
487
|
+
|
|
488
|
+
// Reset on success
|
|
489
|
+
if (this.state === 'HALF_OPEN') {
|
|
490
|
+
this.state = 'CLOSED';
|
|
491
|
+
this.failureCount = 0;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
return result;
|
|
495
|
+
} catch (error) {
|
|
496
|
+
this.failureCount++;
|
|
497
|
+
this.lastFailureTime = Date.now();
|
|
498
|
+
|
|
499
|
+
if (this.failureCount >= this.threshold) {
|
|
500
|
+
this.state = 'OPEN';
|
|
501
|
+
console.warn('Circuit breaker opened');
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
throw error;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
// Usage
|
|
510
|
+
const breaker = new CircuitBreaker(5, 60000);
|
|
511
|
+
|
|
512
|
+
await breaker.execute(() => client.graphql({ query }));
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
---
|
|
516
|
+
|
|
517
|
+
## Logging and Monitoring
|
|
518
|
+
|
|
519
|
+
### Structured Logging
|
|
520
|
+
|
|
521
|
+
```typescript
|
|
522
|
+
import { LoggingService } from '@fluentcommerce/fc-connect-sdk';
|
|
523
|
+
|
|
524
|
+
const log = new LoggingService('inventory-sync');
|
|
525
|
+
|
|
526
|
+
try {
|
|
527
|
+
await processInventory();
|
|
528
|
+
log.info('Inventory sync complete', {
|
|
529
|
+
recordCount: 1000,
|
|
530
|
+
duration: 5000
|
|
531
|
+
});
|
|
532
|
+
} catch (error) {
|
|
533
|
+
log.error('Inventory sync failed', {
|
|
534
|
+
error: error.message,
|
|
535
|
+
stack: error.stack,
|
|
536
|
+
context: {
|
|
537
|
+
filename: 'inventory.csv',
|
|
538
|
+
recordCount: 1000
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
### Error Metrics
|
|
545
|
+
|
|
546
|
+
```typescript
|
|
547
|
+
const errorMetrics = {
|
|
548
|
+
totalErrors: 0,
|
|
549
|
+
errorsByType: {},
|
|
550
|
+
errorsByStatus: {}
|
|
551
|
+
};
|
|
552
|
+
|
|
553
|
+
try {
|
|
554
|
+
await client.graphql({ query });
|
|
555
|
+
} catch (error) {
|
|
556
|
+
errorMetrics.totalErrors++;
|
|
557
|
+
|
|
558
|
+
if (error instanceof FluentAPIError) {
|
|
559
|
+
errorMetrics.errorsByStatus[error.statusCode] =
|
|
560
|
+
(errorMetrics.errorsByStatus[error.statusCode] || 0) + 1;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
errorMetrics.errorsByType[error.constructor.name] =
|
|
564
|
+
(errorMetrics.errorsByType[error.constructor.name] || 0) + 1;
|
|
565
|
+
|
|
566
|
+
throw error;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// Report metrics
|
|
570
|
+
console.log('Error metrics:', errorMetrics);
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
---
|
|
574
|
+
|
|
575
|
+
## Common Error Scenarios
|
|
576
|
+
|
|
577
|
+
### Scenario 1: Transient Network Errors
|
|
578
|
+
|
|
579
|
+
**Symptom:** Intermittent `ECONNRESET` or `ETIMEDOUT` errors
|
|
580
|
+
|
|
581
|
+
**Solution:** Automatic retries with exponential backoff
|
|
582
|
+
|
|
583
|
+
### Scenario 2: Rate Limiting (429)
|
|
584
|
+
|
|
585
|
+
**Symptom:** "Too Many Requests" errors
|
|
586
|
+
|
|
587
|
+
**Solution:** Implement delays between requests
|
|
588
|
+
```typescript
|
|
589
|
+
pagination: {
|
|
590
|
+
pageSize: 100,
|
|
591
|
+
delayMs: 1000 // 1 second delay
|
|
592
|
+
}
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
### Scenario 3: Authentication Token Expiry
|
|
596
|
+
|
|
597
|
+
**Symptom:** 401 errors mid-process
|
|
598
|
+
|
|
599
|
+
**Solution:** FluentClient automatically refreshes tokens
|
|
600
|
+
|
|
601
|
+
### Scenario 4: Partial Batch Failures
|
|
602
|
+
|
|
603
|
+
**Symptom:** Some records succeed, others fail
|
|
604
|
+
|
|
605
|
+
**Solution:** Use PartialBatchRecovery service
|
|
606
|
+
|
|
607
|
+
### Scenario 5: Job Timeouts
|
|
608
|
+
|
|
609
|
+
**Symptom:** Job stuck in PROCESSING state
|
|
610
|
+
|
|
611
|
+
**Solution:** Implement timeout with JobTracker
|
|
612
|
+
```typescript
|
|
613
|
+
const status = await tracker.pollUntilComplete(jobId, {
|
|
614
|
+
timeoutMs: 300000 // 5-minute timeout
|
|
615
|
+
});
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
---
|
|
619
|
+
|
|
620
|
+
## Best Practices
|
|
621
|
+
|
|
622
|
+
1. **Always Handle Errors**
|
|
623
|
+
```typescript
|
|
624
|
+
try {
|
|
625
|
+
await riskyOperation();
|
|
626
|
+
} catch (error) {
|
|
627
|
+
log.error('Operation failed', error);
|
|
628
|
+
// Handle gracefully
|
|
629
|
+
}
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
2. **Use Specific Error Types**
|
|
633
|
+
```typescript
|
|
634
|
+
if (error instanceof AuthenticationError) {
|
|
635
|
+
// Re-authenticate
|
|
636
|
+
} else if (error instanceof ValidationError) {
|
|
637
|
+
// Fix data
|
|
638
|
+
}
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
3. **Implement Retries for Transient Errors**
|
|
642
|
+
```typescript
|
|
643
|
+
retry: {
|
|
644
|
+
maxRetries: 3,
|
|
645
|
+
retryableStatusCodes: [408, 429, 500, 502, 503, 504]
|
|
646
|
+
}
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
4. **Track Failed Records**
|
|
650
|
+
```typescript
|
|
651
|
+
const failed = [];
|
|
652
|
+
for (const record of records) {
|
|
653
|
+
try {
|
|
654
|
+
await process(record);
|
|
655
|
+
} catch (error) {
|
|
656
|
+
failed.push({ record, error });
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
// Export failed records for review
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
5. **Set Appropriate Timeouts**
|
|
663
|
+
```typescript
|
|
664
|
+
const controller = new AbortController();
|
|
665
|
+
setTimeout(() => controller.abort(), 30000);
|
|
666
|
+
await client.graphql({ query, signal: controller.signal });
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
---
|
|
670
|
+
|
|
671
|
+
## Troubleshooting
|
|
672
|
+
|
|
673
|
+
### Debug Mode
|
|
674
|
+
|
|
675
|
+
Enable verbose logging:
|
|
676
|
+
```typescript
|
|
677
|
+
const log = new LoggingService('connector', { level: 'debug' });
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
### Error Stack Traces
|
|
681
|
+
|
|
682
|
+
Preserve full stack traces:
|
|
683
|
+
```typescript
|
|
684
|
+
try {
|
|
685
|
+
await operation();
|
|
686
|
+
} catch (error) {
|
|
687
|
+
console.error('Full error:', {
|
|
688
|
+
message: error.message,
|
|
689
|
+
stack: error.stack,
|
|
690
|
+
cause: error.cause
|
|
691
|
+
});
|
|
692
|
+
throw error;
|
|
693
|
+
}
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
---
|
|
697
|
+
|
|
698
|
+
## See Also
|
|
699
|
+
|
|
700
|
+
**Related Modules:**
|
|
701
|
+
- [Module 05: Services](./api-reference-05-services.md) - PartialBatchRecovery, JobTracker
|
|
702
|
+
- [Module 03: Authentication](./api-reference-03-authentication.md) - Token refresh handling
|
|
703
|
+
|
|
704
|
+
**Complete Guides:**
|
|
705
|
+
- [Error Handling Guide](../../../03-PATTERN-GUIDES/error-handling/error-handling-readme.md) - Comprehensive error patterns
|
|
706
|
+
- [Batch Processing](../../ingestion/modules/02-core-guides-ingestion-06-batch-api.md) - Batch error recovery
|
|
707
|
+
|
|
708
|
+
**Templates:**
|
|
709
|
+
- [Error Handling Patterns](../../../01-TEMPLATES/patterns/error-handling-retry.md)
|
|
710
|
+
|
|
711
|
+
---
|
|
712
|
+
|
|
713
|
+
**Navigation:**
|
|
714
|
+
- [Back to Module List](./readme.md)
|
|
715
|
+
- [Previous: Module 10 - Extraction](./api-reference-10-extraction.md)
|
|
716
|
+
- [Next: Module 12 - Testing](./api-reference-12-testing.md)
|