@fluentcommerce/fc-connect-sdk 0.1.53 → 0.1.55
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 +30 -2
- package/README.md +39 -0
- package/dist/cjs/auth/index.d.ts +3 -0
- package/dist/cjs/auth/index.js +13 -0
- package/dist/cjs/auth/profile-loader.d.ts +18 -0
- package/dist/cjs/auth/profile-loader.js +208 -0
- package/dist/cjs/client-factory.d.ts +4 -0
- package/dist/cjs/client-factory.js +10 -0
- package/dist/cjs/clients/fluent-client.js +13 -6
- package/dist/cjs/index.d.ts +3 -1
- package/dist/cjs/index.js +8 -2
- package/dist/cjs/utils/pagination-helpers.js +38 -2
- package/dist/cjs/versori/fluent-versori-client.js +11 -5
- package/dist/esm/auth/index.d.ts +3 -0
- package/dist/esm/auth/index.js +2 -0
- package/dist/esm/auth/profile-loader.d.ts +18 -0
- package/dist/esm/auth/profile-loader.js +169 -0
- package/dist/esm/client-factory.d.ts +4 -0
- package/dist/esm/client-factory.js +9 -0
- package/dist/esm/clients/fluent-client.js +13 -6
- package/dist/esm/index.d.ts +3 -1
- package/dist/esm/index.js +2 -1
- 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/dist/types/auth/index.d.ts +3 -0
- package/dist/types/auth/profile-loader.d.ts +18 -0
- package/dist/types/client-factory.d.ts +4 -0
- package/dist/types/index.d.ts +3 -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 -482
- 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
|
@@ -1,671 +1,671 @@
|
|
|
1
|
-
# Module 5: Calling Patterns
|
|
2
|
-
|
|
3
|
-
**Level:** Intermediate
|
|
4
|
-
**Estimated Time:** 30 minutes
|
|
5
|
-
|
|
6
|
-
## Overview
|
|
7
|
-
|
|
8
|
-
This module provides practical code patterns for handling errors in your Fluent Commerce integrations, from basic try-catch blocks to comprehensive error handling with monitoring.
|
|
9
|
-
|
|
10
|
-
## Learning Objectives
|
|
11
|
-
|
|
12
|
-
By the end of this module, you will:
|
|
13
|
-
- ✅ Write basic error handling code with try-catch
|
|
14
|
-
- ✅ Implement comprehensive error handling for production systems
|
|
15
|
-
- ✅ Add error monitoring and metrics collection
|
|
16
|
-
- ✅ Know when to retry vs when to fail immediately
|
|
17
|
-
|
|
18
|
-
## Basic Error Handling
|
|
19
|
-
|
|
20
|
-
### Logging Setup
|
|
21
|
-
|
|
22
|
-
**First, set up logging based on your runtime:**
|
|
23
|
-
|
|
24
|
-
```typescript
|
|
25
|
-
// Standalone (Node.js/Deno)
|
|
26
|
-
import { createConsoleLogger, toStructuredLogger } from '@fluentcommerce/fc-connect-sdk';
|
|
27
|
-
const logger = toStructuredLogger(createConsoleLogger(), { service: 'OrderProcessing' });
|
|
28
|
-
|
|
29
|
-
// Versori Platform
|
|
30
|
-
const { log: logger } = ctx; // Use native platform log
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
### Minimal Pattern
|
|
34
|
-
|
|
35
|
-
The simplest error handling pattern - catch and log:
|
|
36
|
-
|
|
37
|
-
```typescript
|
|
38
|
-
import {
|
|
39
|
-
XMLParserService,
|
|
40
|
-
GraphQLMutationMapper,
|
|
41
|
-
FluentClient,
|
|
42
|
-
createConsoleLogger,
|
|
43
|
-
toStructuredLogger
|
|
44
|
-
} from '@fluentcommerce/fc-connect-sdk';
|
|
45
|
-
|
|
46
|
-
// Standalone
|
|
47
|
-
const logger = toStructuredLogger(createConsoleLogger(), { service: 'OrderProcessing' });
|
|
48
|
-
|
|
49
|
-
// Versori Platform
|
|
50
|
-
// const { log: logger } = ctx;
|
|
51
|
-
|
|
52
|
-
async function processOrder(xmlContent: string) {
|
|
53
|
-
try {
|
|
54
|
-
// Parse XML
|
|
55
|
-
const parser = new XMLParserService();
|
|
56
|
-
const parsed = await parser.parse(xmlContent);
|
|
57
|
-
|
|
58
|
-
// Map to GraphQL mutation
|
|
59
|
-
const mapper = new GraphQLMutationMapper(mappingConfig, logger, { fluentClient: client });
|
|
60
|
-
const payload = await mapper.map(parsed);
|
|
61
|
-
|
|
62
|
-
// Execute mutation
|
|
63
|
-
// Throws GraphQLExecutionError on failure
|
|
64
|
-
const result = await client.graphql(payload);
|
|
65
|
-
|
|
66
|
-
return result.data;
|
|
67
|
-
|
|
68
|
-
} catch (error) {
|
|
69
|
-
logger.error('Order processing failed', error);
|
|
70
|
-
throw error; // Re-throw for upstream handling
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
**Key points:**
|
|
76
|
-
- ✅ Wraps all operations in try-catch
|
|
77
|
-
- ✅ Logs the error
|
|
78
|
-
- ✅ Re-throws error (doesn't silence failures)
|
|
79
|
-
- ❌ No specific error type handling
|
|
80
|
-
- ❌ No retry logic
|
|
81
|
-
|
|
82
|
-
### Intermediate Pattern with Type Checking
|
|
83
|
-
|
|
84
|
-
Add specific handling for different error types:
|
|
85
|
-
|
|
86
|
-
```typescript
|
|
87
|
-
import {
|
|
88
|
-
XMLParserService,
|
|
89
|
-
GraphQLMutationMapper,
|
|
90
|
-
FluentClient,
|
|
91
|
-
FileParsingError,
|
|
92
|
-
PathResolutionError,
|
|
93
|
-
MappingError,
|
|
94
|
-
IngestionError,
|
|
95
|
-
GraphQLExecutionError
|
|
96
|
-
} from '@fluentcommerce/fc-connect-sdk';
|
|
97
|
-
|
|
98
|
-
async function processOrder(xmlContent: string) {
|
|
99
|
-
try {
|
|
100
|
-
// Parse XML
|
|
101
|
-
const parser = new XMLParserService();
|
|
102
|
-
const parsed = await parser.parse(xmlContent);
|
|
103
|
-
|
|
104
|
-
// Map to GraphQL mutation
|
|
105
|
-
const mapper = new GraphQLMutationMapper(mappingConfig, logger, { fluentClient: client });
|
|
106
|
-
const payload = await mapper.map(parsed);
|
|
107
|
-
|
|
108
|
-
// Execute mutation (only if no errors above)
|
|
109
|
-
// Throws GraphQLExecutionError on failure
|
|
110
|
-
const result = await client.graphql(payload);
|
|
111
|
-
|
|
112
|
-
return result.data; // ✅ Complete data or nothing
|
|
113
|
-
|
|
114
|
-
} catch (error) {
|
|
115
|
-
// ✅ IMPORTANT: No partial data - mutation never executed or was rejected
|
|
116
|
-
|
|
117
|
-
if (error instanceof GraphQLExecutionError) {
|
|
118
|
-
// GraphQL errors from Fluent
|
|
119
|
-
logger.error('GraphQL error:', {
|
|
120
|
-
message: error.message,
|
|
121
|
-
errors: error.getErrorMessages(),
|
|
122
|
-
query: error.query
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
// Classify errors to determine retry strategy
|
|
126
|
-
if (error.isAuthError()) {
|
|
127
|
-
// Auth error
|
|
128
|
-
} else if (error.isValidationError()) {
|
|
129
|
-
// Validation error
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
throw error;
|
|
133
|
-
} else if (error instanceof FileParsingError) {
|
|
134
|
-
// XML parsing failed
|
|
135
|
-
logger.error('Invalid XML file:', {
|
|
136
|
-
code: error.code,
|
|
137
|
-
fileName: error.fileName,
|
|
138
|
-
lineNumber: error.lineNumber,
|
|
139
|
-
message: error.message
|
|
140
|
-
});
|
|
141
|
-
// Alert user: File is corrupt or invalid format
|
|
142
|
-
throw error; // Don't retry
|
|
143
|
-
|
|
144
|
-
} else if (error instanceof PathResolutionError) {
|
|
145
|
-
// Wrong path in mapping config
|
|
146
|
-
logger.error('Path resolution failed:', {
|
|
147
|
-
path: error.path,
|
|
148
|
-
message: error.message
|
|
149
|
-
});
|
|
150
|
-
// Alert developer: Fix mapping configuration
|
|
151
|
-
throw error; // Don't retry
|
|
152
|
-
|
|
153
|
-
} else if (error instanceof MappingError) {
|
|
154
|
-
// Required field missing or type mismatch
|
|
155
|
-
logger.error('Mapping failed:', {
|
|
156
|
-
field: error.field,
|
|
157
|
-
sourcePath: error.sourcePath,
|
|
158
|
-
message: error.message
|
|
159
|
-
});
|
|
160
|
-
// Alert developer: Data doesn't match mapping expectations
|
|
161
|
-
throw error; // Don't retry
|
|
162
|
-
|
|
163
|
-
} else if (error instanceof IngestionError) {
|
|
164
|
-
logger.error('Ingestion error:', error.toJSON());
|
|
165
|
-
|
|
166
|
-
// Retry if transient error
|
|
167
|
-
if (error.isRetryable()) {
|
|
168
|
-
return scheduleRetry();
|
|
169
|
-
}
|
|
170
|
-
throw error; // Non-retryable
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// Unknown error
|
|
174
|
-
throw error;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
**Key points:**
|
|
180
|
-
- ✅ Checks specific error types with `instanceof`
|
|
181
|
-
- ✅ Logs error-specific context
|
|
182
|
-
- ✅ Uses `error.isRetryable()` for retry decisions
|
|
183
|
-
- ✅ Different handling for different error types
|
|
184
|
-
- ✅ Clear comments explaining each case
|
|
185
|
-
|
|
186
|
-
## Comprehensive Error Handling
|
|
187
|
-
|
|
188
|
-
### Production-Ready Pattern with Retry Logic
|
|
189
|
-
|
|
190
|
-
Complete error handling for production systems:
|
|
191
|
-
|
|
192
|
-
```typescript
|
|
193
|
-
import {
|
|
194
|
-
createClient,
|
|
195
|
-
XMLParserService,
|
|
196
|
-
GraphQLMutationMapper,
|
|
197
|
-
FileParsingError,
|
|
198
|
-
PathResolutionError,
|
|
199
|
-
MappingError,
|
|
200
|
-
ValidationError,
|
|
201
|
-
IngestionError,
|
|
202
|
-
IngestionErrorCode,
|
|
203
|
-
GraphQLExecutionError,
|
|
204
|
-
FluentAPIError
|
|
205
|
-
} from '@fluentcommerce/fc-connect-sdk';
|
|
206
|
-
|
|
207
|
-
async function processOrderWithRetry(
|
|
208
|
-
xmlContent: string,
|
|
209
|
-
maxRetries = 3
|
|
210
|
-
): Promise<any> {
|
|
211
|
-
let attempt = 0;
|
|
212
|
-
|
|
213
|
-
while (attempt < maxRetries) {
|
|
214
|
-
try {
|
|
215
|
-
attempt++;
|
|
216
|
-
|
|
217
|
-
// Parse XML
|
|
218
|
-
const parser = new XMLParserService();
|
|
219
|
-
let parsed;
|
|
220
|
-
|
|
221
|
-
try {
|
|
222
|
-
parsed = await parser.parse(xmlContent);
|
|
223
|
-
} catch (error) {
|
|
224
|
-
if (error instanceof FileParsingError) {
|
|
225
|
-
// Parse error = permanent failure, don't retry
|
|
226
|
-
logger.error('XML parse error (permanent):', {
|
|
227
|
-
code: error.code,
|
|
228
|
-
fileName: error.fileName,
|
|
229
|
-
message: error.message
|
|
230
|
-
});
|
|
231
|
-
throw error; // Don't retry
|
|
232
|
-
}
|
|
233
|
-
throw error;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// Map to mutation
|
|
237
|
-
const mapper = new GraphQLMutationMapper(mappingConfig, logger, { fluentClient: client });
|
|
238
|
-
let payload;
|
|
239
|
-
|
|
240
|
-
try {
|
|
241
|
-
payload = await mapper.map(parsed);
|
|
242
|
-
} catch (error) {
|
|
243
|
-
if (error instanceof PathResolutionError) {
|
|
244
|
-
// Wrong path = permanent failure (config issue)
|
|
245
|
-
logger.error('Path error (permanent):', {
|
|
246
|
-
path: error.path,
|
|
247
|
-
message: error.message
|
|
248
|
-
});
|
|
249
|
-
throw error; // Don't retry
|
|
250
|
-
|
|
251
|
-
} else if (error instanceof MappingError) {
|
|
252
|
-
// Mapping error = permanent failure (data/config issue)
|
|
253
|
-
logger.error('Mapping error (permanent):', {
|
|
254
|
-
field: error.field,
|
|
255
|
-
sourcePath: error.sourcePath,
|
|
256
|
-
message: error.message
|
|
257
|
-
});
|
|
258
|
-
throw error; // Don't retry
|
|
259
|
-
}
|
|
260
|
-
throw error;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
// Execute mutation
|
|
264
|
-
const result = await client.graphql(payload);
|
|
265
|
-
|
|
266
|
-
// Success - return complete data
|
|
267
|
-
return result.data;
|
|
268
|
-
|
|
269
|
-
} catch (error) {
|
|
270
|
-
// Check if error is retryable
|
|
271
|
-
|
|
272
|
-
// 1. GraphQL Execution Error (e.g. Timeout/Network in GraphQL response)
|
|
273
|
-
if (error instanceof GraphQLExecutionError) {
|
|
274
|
-
const graphqlError = error.graphqlErrors[0];
|
|
275
|
-
|
|
276
|
-
if (graphqlError.extensions?.code === 'TIMEOUT' ||
|
|
277
|
-
graphqlError.extensions?.code === 'NETWORK_ERROR') {
|
|
278
|
-
|
|
279
|
-
if (attempt < maxRetries) {
|
|
280
|
-
await delay(1000 * attempt);
|
|
281
|
-
continue; // Retry
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
// Permanent GraphQL error
|
|
285
|
-
throw error;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
// 2. Ingestion Error (Network, etc.)
|
|
289
|
-
if (error instanceof IngestionError && error.isRetryable()) {
|
|
290
|
-
if (attempt < maxRetries) {
|
|
291
|
-
logger.warn(`Retryable error, attempt ${attempt}/${maxRetries}`, {
|
|
292
|
-
code: error.code,
|
|
293
|
-
message: error.message
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
// Exponential backoff
|
|
297
|
-
await delay(1000 * Math.pow(2, attempt - 1));
|
|
298
|
-
continue;
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
// 3. Fluent API Error (HTTP 5xx)
|
|
303
|
-
if (error instanceof FluentAPIError && error.statusCode >= 500) {
|
|
304
|
-
if (attempt < maxRetries) {
|
|
305
|
-
await delay(1000 * attempt);
|
|
306
|
-
continue;
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
// Non-retryable error or max retries exceeded
|
|
311
|
-
logger.error('Order processing failed:', {
|
|
312
|
-
attempt,
|
|
313
|
-
error: error instanceof IngestionError ? error.toJSON() : error.message
|
|
314
|
-
});
|
|
315
|
-
|
|
316
|
-
throw error;
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
throw new Error('Max retries exceeded');
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
function delay(ms: number): Promise<void> {
|
|
324
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
325
|
-
}
|
|
326
|
-
```
|
|
327
|
-
|
|
328
|
-
**Key points:**
|
|
329
|
-
- ✅ Retry loop with max attempts
|
|
330
|
-
- ✅ Specific handling at each stage (parse, map, execute)
|
|
331
|
-
- ✅ Permanent errors immediately thrown (no retry)
|
|
332
|
-
- ✅ Transient errors retried with exponential backoff
|
|
333
|
-
- ✅ GraphQL errors classified by code
|
|
334
|
-
- ✅ Detailed logging at each stage
|
|
335
|
-
|
|
336
|
-
## Error Handling with Monitoring
|
|
337
|
-
|
|
338
|
-
### Adding Metrics Collection
|
|
339
|
-
|
|
340
|
-
Track error patterns for alerting and analysis:
|
|
341
|
-
|
|
342
|
-
```typescript
|
|
343
|
-
import {
|
|
344
|
-
IngestionError,
|
|
345
|
-
IngestionErrorCode,
|
|
346
|
-
MappingError,
|
|
347
|
-
PathResolutionError
|
|
348
|
-
} from '@fluentcommerce/fc-connect-sdk';
|
|
349
|
-
|
|
350
|
-
class ErrorMonitor {
|
|
351
|
-
private errorCounts = new Map<string, number>();
|
|
352
|
-
private lastErrors = new Map<string, Date>();
|
|
353
|
-
|
|
354
|
-
recordError(error: Error): void {
|
|
355
|
-
let errorType = 'UNKNOWN';
|
|
356
|
-
|
|
357
|
-
if (error instanceof IngestionError) {
|
|
358
|
-
errorType = error.code;
|
|
359
|
-
} else if (error instanceof MappingError) {
|
|
360
|
-
errorType = 'MAPPING_ERROR';
|
|
361
|
-
} else if (error instanceof PathResolutionError) {
|
|
362
|
-
errorType = 'PATH_RESOLUTION_ERROR';
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
const count = this.errorCounts.get(errorType) || 0;
|
|
366
|
-
this.errorCounts.set(errorType, count + 1);
|
|
367
|
-
this.lastErrors.set(errorType, new Date());
|
|
368
|
-
|
|
369
|
-
// Alert if error rate is high
|
|
370
|
-
if (count + 1 > 10) {
|
|
371
|
-
this.alertHighErrorRate(errorType, count + 1);
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
getMetrics() {
|
|
376
|
-
return {
|
|
377
|
-
errorCounts: Object.fromEntries(this.errorCounts),
|
|
378
|
-
lastErrors: Object.fromEntries(this.lastErrors),
|
|
379
|
-
timestamp: new Date().toISOString()
|
|
380
|
-
};
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
private alertHighErrorRate(errorType: string, count: number): void {
|
|
384
|
-
console.error(`HIGH ERROR RATE: ${errorType} - ${count} errors`);
|
|
385
|
-
// Send alert to monitoring system (PagerDuty, Slack, etc.)
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
const errorMonitor = new ErrorMonitor();
|
|
390
|
-
|
|
391
|
-
async function processWithMonitoring(data: any) {
|
|
392
|
-
try {
|
|
393
|
-
return await processOrder(data);
|
|
394
|
-
} catch (error) {
|
|
395
|
-
errorMonitor.recordError(error);
|
|
396
|
-
throw error;
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
```
|
|
400
|
-
|
|
401
|
-
**Features:**
|
|
402
|
-
- ✅ Tracks error counts by type
|
|
403
|
-
- ✅ Records last occurrence of each error
|
|
404
|
-
- ✅ Alerts on high error rates
|
|
405
|
-
- ✅ Provides metrics for dashboards
|
|
406
|
-
|
|
407
|
-
### Integration with Monitoring Systems
|
|
408
|
-
|
|
409
|
-
Send errors to external monitoring:
|
|
410
|
-
|
|
411
|
-
```typescript
|
|
412
|
-
import { IngestionError } from '@fluentcommerce/fc-connect-sdk';
|
|
413
|
-
|
|
414
|
-
async function processWithExternalMonitoring(data: any) {
|
|
415
|
-
try {
|
|
416
|
-
return await processOrder(data);
|
|
417
|
-
} catch (error) {
|
|
418
|
-
// Send to monitoring service
|
|
419
|
-
if (error instanceof IngestionError) {
|
|
420
|
-
await sendToDatadog({
|
|
421
|
-
metric: 'ingestion.error',
|
|
422
|
-
tags: [
|
|
423
|
-
`error_code:${error.code}`,
|
|
424
|
-
`retryable:${error.isRetryable()}`
|
|
425
|
-
],
|
|
426
|
-
value: 1
|
|
427
|
-
});
|
|
428
|
-
|
|
429
|
-
await sendToSentry({
|
|
430
|
-
message: error.message,
|
|
431
|
-
level: 'error',
|
|
432
|
-
extra: error.toJSON()
|
|
433
|
-
});
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
throw error;
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
async function sendToDatadog(metric: any) {
|
|
441
|
-
// Datadog integration
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
async function sendToSentry(event: any) {
|
|
445
|
-
// Sentry integration
|
|
446
|
-
}
|
|
447
|
-
```
|
|
448
|
-
|
|
449
|
-
## Stage-Specific Error Handling
|
|
450
|
-
|
|
451
|
-
### Parsing Stage
|
|
452
|
-
|
|
453
|
-
Handle parsing errors separately:
|
|
454
|
-
|
|
455
|
-
```typescript
|
|
456
|
-
async function safeParse(content: string, fileName: string): Promise<any> {
|
|
457
|
-
try {
|
|
458
|
-
const parser = new XMLParserService();
|
|
459
|
-
return await parser.parse(content);
|
|
460
|
-
} catch (error) {
|
|
461
|
-
if (error instanceof FileParsingError) {
|
|
462
|
-
logger.error('Parsing failed - permanent error', {
|
|
463
|
-
fileName,
|
|
464
|
-
lineNumber: error.lineNumber,
|
|
465
|
-
code: error.code
|
|
466
|
-
});
|
|
467
|
-
|
|
468
|
-
// Save to dead letter queue for manual review
|
|
469
|
-
await saveToDeadLetterQueue({
|
|
470
|
-
fileName,
|
|
471
|
-
content,
|
|
472
|
-
error: error.toJSON()
|
|
473
|
-
});
|
|
474
|
-
|
|
475
|
-
throw error; // Don't retry
|
|
476
|
-
}
|
|
477
|
-
throw error;
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
```
|
|
481
|
-
|
|
482
|
-
### Mapping Stage
|
|
483
|
-
|
|
484
|
-
Handle mapping errors with detailed context:
|
|
485
|
-
|
|
486
|
-
```typescript
|
|
487
|
-
async function safeMap(parsed: any, context: any): Promise<any> {
|
|
488
|
-
try {
|
|
489
|
-
const mapper = new GraphQLMutationMapper(mappingConfig, logger, { fluentClient: client });
|
|
490
|
-
return await mapper.map(parsed);
|
|
491
|
-
} catch (error) {
|
|
492
|
-
if (error instanceof MappingError) {
|
|
493
|
-
logger.error('Mapping failed - check data or config', {
|
|
494
|
-
field: error.field,
|
|
495
|
-
sourcePath: error.sourcePath,
|
|
496
|
-
context
|
|
497
|
-
});
|
|
498
|
-
|
|
499
|
-
// Log sample data for debugging
|
|
500
|
-
await logSampleData({
|
|
501
|
-
field: error.field,
|
|
502
|
-
sourcePath: error.sourcePath,
|
|
503
|
-
sourceData: parsed
|
|
504
|
-
});
|
|
505
|
-
|
|
506
|
-
throw error; // Don't retry
|
|
507
|
-
} else if (error instanceof PathResolutionError) {
|
|
508
|
-
logger.error('Path resolution failed - check config', {
|
|
509
|
-
path: error.path,
|
|
510
|
-
availablePaths: Object.keys(parsed)
|
|
511
|
-
});
|
|
512
|
-
|
|
513
|
-
throw error; // Don't retry
|
|
514
|
-
}
|
|
515
|
-
throw error;
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
```
|
|
519
|
-
|
|
520
|
-
### Execution Stage
|
|
521
|
-
|
|
522
|
-
Handle API errors with retry logic:
|
|
523
|
-
|
|
524
|
-
```typescript
|
|
525
|
-
async function safeExecute(
|
|
526
|
-
payload: any,
|
|
527
|
-
maxRetries = 3
|
|
528
|
-
): Promise<any> {
|
|
529
|
-
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
530
|
-
try {
|
|
531
|
-
const result = await client.graphql(payload);
|
|
532
|
-
return result.data;
|
|
533
|
-
|
|
534
|
-
} catch (error) {
|
|
535
|
-
// Check for retryable GraphQL errors
|
|
536
|
-
if (error instanceof GraphQLExecutionError) {
|
|
537
|
-
const firstError = error.graphqlErrors[0];
|
|
538
|
-
if (firstError.extensions?.code === 'TIMEOUT' && attempt < maxRetries) {
|
|
539
|
-
const delay = Math.pow(2, attempt) * 1000;
|
|
540
|
-
logger.warn(`GraphQL timeout, retrying in ${delay}ms`, { attempt });
|
|
541
|
-
await new Promise(resolve => setTimeout(resolve, delay));
|
|
542
|
-
continue;
|
|
543
|
-
}
|
|
544
|
-
throw error;
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
if (error instanceof IngestionError &&
|
|
548
|
-
error.isRetryable() &&
|
|
549
|
-
attempt < maxRetries) {
|
|
550
|
-
|
|
551
|
-
const delay = Math.pow(2, attempt) * 1000;
|
|
552
|
-
logger.warn(`Retrying after ${delay}ms`, { attempt, error: error.code });
|
|
553
|
-
await new Promise(resolve => setTimeout(resolve, delay));
|
|
554
|
-
continue;
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
throw error;
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
throw new Error('Max retries exceeded');
|
|
562
|
-
}
|
|
563
|
-
```
|
|
564
|
-
|
|
565
|
-
## Error Context Enrichment
|
|
566
|
-
|
|
567
|
-
### Adding Context to Errors
|
|
568
|
-
|
|
569
|
-
Enrich errors with business context:
|
|
570
|
-
|
|
571
|
-
```typescript
|
|
572
|
-
async function processOrderWithContext(xmlContent: string, metadata: any) {
|
|
573
|
-
try {
|
|
574
|
-
return await processOrder(xmlContent);
|
|
575
|
-
} catch (error) {
|
|
576
|
-
// Enrich error with business context
|
|
577
|
-
const enrichedError = new Error(error.message);
|
|
578
|
-
enrichedError.cause = error;
|
|
579
|
-
enrichedError.context = {
|
|
580
|
-
...metadata,
|
|
581
|
-
timestamp: new Date().toISOString(),
|
|
582
|
-
environment: process.env.NODE_ENV,
|
|
583
|
-
version: process.env.APP_VERSION
|
|
584
|
-
};
|
|
585
|
-
|
|
586
|
-
if (error instanceof IngestionError) {
|
|
587
|
-
enrichedError.context.errorCode = error.code;
|
|
588
|
-
enrichedError.context.retryable = error.isRetryable();
|
|
589
|
-
enrichedError.context.originalContext = error.context;
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
logger.error('Order processing failed with context:', enrichedError.context);
|
|
593
|
-
throw enrichedError;
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
```
|
|
597
|
-
|
|
598
|
-
## Key Takeaways
|
|
599
|
-
|
|
600
|
-
- 🎯 **Always use try-catch** - Never call SDK methods without error handling
|
|
601
|
-
- 🎯 **Check error types** - Use `instanceof` for specific handling
|
|
602
|
-
- 🎯 **Re-throw errors** - Don't silence failures
|
|
603
|
-
- 🎯 **Log with context** - Include all relevant error details
|
|
604
|
-
- 🎯 **Monitor patterns** - Track error rates for alerting
|
|
605
|
-
- 🎯 **Enrich errors** - Add business context before logging
|
|
606
|
-
|
|
607
|
-
## Practice Exercise
|
|
608
|
-
|
|
609
|
-
Improve this error handling code:
|
|
610
|
-
|
|
611
|
-
```typescript
|
|
612
|
-
// ❌ POOR ERROR HANDLING
|
|
613
|
-
async function processData(data: any) {
|
|
614
|
-
try {
|
|
615
|
-
const result = await client.graphql(query);
|
|
616
|
-
return result.data;
|
|
617
|
-
} catch (error) {
|
|
618
|
-
console.log('Error');
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
```
|
|
622
|
-
|
|
623
|
-
<details>
|
|
624
|
-
<summary>Click to see improved version</summary>
|
|
625
|
-
|
|
626
|
-
```typescript
|
|
627
|
-
// ✅ IMPROVED ERROR HANDLING
|
|
628
|
-
import {
|
|
629
|
-
FileParsingError,
|
|
630
|
-
MappingError,
|
|
631
|
-
IngestionError
|
|
632
|
-
} from '@fluentcommerce/fc-connect-sdk';
|
|
633
|
-
|
|
634
|
-
async function processData(data: any, context: any) {
|
|
635
|
-
try {
|
|
636
|
-
const result = await client.graphql(query);
|
|
637
|
-
|
|
638
|
-
if (result.errors) {
|
|
639
|
-
throw new Error(`GraphQL error: ${result.errors[0].message}`);
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
return result.data;
|
|
643
|
-
|
|
644
|
-
} catch (error) {
|
|
645
|
-
// Log with full context
|
|
646
|
-
logger.error('Data processing failed:', {
|
|
647
|
-
context,
|
|
648
|
-
error: error instanceof IngestionError ? error.toJSON() : error.message
|
|
649
|
-
});
|
|
650
|
-
|
|
651
|
-
// Check if retryable
|
|
652
|
-
if (error instanceof IngestionError && error.isRetryable()) {
|
|
653
|
-
return scheduleRetry(data, context);
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
// Re-throw for upstream handling
|
|
657
|
-
throw error;
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
```
|
|
661
|
-
|
|
662
|
-
</details>
|
|
663
|
-
|
|
664
|
-
## Next Steps
|
|
665
|
-
|
|
666
|
-
Continue to [Module 6: Retry Strategies →](./error-handling-06-retry-strategies.md) to learn advanced retry patterns with exponential backoff.
|
|
667
|
-
|
|
668
|
-
---
|
|
669
|
-
|
|
670
|
-
**Previous:** [← Module 4: Error Scenarios](./error-handling-04-error-scenarios.md)
|
|
671
|
-
**Next:** [Module 6: Retry Strategies →](./error-handling-06-retry-strategies.md)
|
|
1
|
+
# Module 5: Calling Patterns
|
|
2
|
+
|
|
3
|
+
**Level:** Intermediate
|
|
4
|
+
**Estimated Time:** 30 minutes
|
|
5
|
+
|
|
6
|
+
## Overview
|
|
7
|
+
|
|
8
|
+
This module provides practical code patterns for handling errors in your Fluent Commerce integrations, from basic try-catch blocks to comprehensive error handling with monitoring.
|
|
9
|
+
|
|
10
|
+
## Learning Objectives
|
|
11
|
+
|
|
12
|
+
By the end of this module, you will:
|
|
13
|
+
- ✅ Write basic error handling code with try-catch
|
|
14
|
+
- ✅ Implement comprehensive error handling for production systems
|
|
15
|
+
- ✅ Add error monitoring and metrics collection
|
|
16
|
+
- ✅ Know when to retry vs when to fail immediately
|
|
17
|
+
|
|
18
|
+
## Basic Error Handling
|
|
19
|
+
|
|
20
|
+
### Logging Setup
|
|
21
|
+
|
|
22
|
+
**First, set up logging based on your runtime:**
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
// Standalone (Node.js/Deno)
|
|
26
|
+
import { createConsoleLogger, toStructuredLogger } from '@fluentcommerce/fc-connect-sdk';
|
|
27
|
+
const logger = toStructuredLogger(createConsoleLogger(), { service: 'OrderProcessing' });
|
|
28
|
+
|
|
29
|
+
// Versori Platform
|
|
30
|
+
const { log: logger } = ctx; // Use native platform log
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Minimal Pattern
|
|
34
|
+
|
|
35
|
+
The simplest error handling pattern - catch and log:
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import {
|
|
39
|
+
XMLParserService,
|
|
40
|
+
GraphQLMutationMapper,
|
|
41
|
+
FluentClient,
|
|
42
|
+
createConsoleLogger,
|
|
43
|
+
toStructuredLogger
|
|
44
|
+
} from '@fluentcommerce/fc-connect-sdk';
|
|
45
|
+
|
|
46
|
+
// Standalone
|
|
47
|
+
const logger = toStructuredLogger(createConsoleLogger(), { service: 'OrderProcessing' });
|
|
48
|
+
|
|
49
|
+
// Versori Platform
|
|
50
|
+
// const { log: logger } = ctx;
|
|
51
|
+
|
|
52
|
+
async function processOrder(xmlContent: string) {
|
|
53
|
+
try {
|
|
54
|
+
// Parse XML
|
|
55
|
+
const parser = new XMLParserService();
|
|
56
|
+
const parsed = await parser.parse(xmlContent);
|
|
57
|
+
|
|
58
|
+
// Map to GraphQL mutation
|
|
59
|
+
const mapper = new GraphQLMutationMapper(mappingConfig, logger, { fluentClient: client });
|
|
60
|
+
const payload = await mapper.map(parsed);
|
|
61
|
+
|
|
62
|
+
// Execute mutation
|
|
63
|
+
// Throws GraphQLExecutionError on failure
|
|
64
|
+
const result = await client.graphql(payload);
|
|
65
|
+
|
|
66
|
+
return result.data;
|
|
67
|
+
|
|
68
|
+
} catch (error) {
|
|
69
|
+
logger.error('Order processing failed', error);
|
|
70
|
+
throw error; // Re-throw for upstream handling
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Key points:**
|
|
76
|
+
- ✅ Wraps all operations in try-catch
|
|
77
|
+
- ✅ Logs the error
|
|
78
|
+
- ✅ Re-throws error (doesn't silence failures)
|
|
79
|
+
- ❌ No specific error type handling
|
|
80
|
+
- ❌ No retry logic
|
|
81
|
+
|
|
82
|
+
### Intermediate Pattern with Type Checking
|
|
83
|
+
|
|
84
|
+
Add specific handling for different error types:
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
import {
|
|
88
|
+
XMLParserService,
|
|
89
|
+
GraphQLMutationMapper,
|
|
90
|
+
FluentClient,
|
|
91
|
+
FileParsingError,
|
|
92
|
+
PathResolutionError,
|
|
93
|
+
MappingError,
|
|
94
|
+
IngestionError,
|
|
95
|
+
GraphQLExecutionError
|
|
96
|
+
} from '@fluentcommerce/fc-connect-sdk';
|
|
97
|
+
|
|
98
|
+
async function processOrder(xmlContent: string) {
|
|
99
|
+
try {
|
|
100
|
+
// Parse XML
|
|
101
|
+
const parser = new XMLParserService();
|
|
102
|
+
const parsed = await parser.parse(xmlContent);
|
|
103
|
+
|
|
104
|
+
// Map to GraphQL mutation
|
|
105
|
+
const mapper = new GraphQLMutationMapper(mappingConfig, logger, { fluentClient: client });
|
|
106
|
+
const payload = await mapper.map(parsed);
|
|
107
|
+
|
|
108
|
+
// Execute mutation (only if no errors above)
|
|
109
|
+
// Throws GraphQLExecutionError on failure
|
|
110
|
+
const result = await client.graphql(payload);
|
|
111
|
+
|
|
112
|
+
return result.data; // ✅ Complete data or nothing
|
|
113
|
+
|
|
114
|
+
} catch (error) {
|
|
115
|
+
// ✅ IMPORTANT: No partial data - mutation never executed or was rejected
|
|
116
|
+
|
|
117
|
+
if (error instanceof GraphQLExecutionError) {
|
|
118
|
+
// GraphQL errors from Fluent
|
|
119
|
+
logger.error('GraphQL error:', {
|
|
120
|
+
message: error.message,
|
|
121
|
+
errors: error.getErrorMessages(),
|
|
122
|
+
query: error.query
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// Classify errors to determine retry strategy
|
|
126
|
+
if (error.isAuthError()) {
|
|
127
|
+
// Auth error
|
|
128
|
+
} else if (error.isValidationError()) {
|
|
129
|
+
// Validation error
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
throw error;
|
|
133
|
+
} else if (error instanceof FileParsingError) {
|
|
134
|
+
// XML parsing failed
|
|
135
|
+
logger.error('Invalid XML file:', {
|
|
136
|
+
code: error.code,
|
|
137
|
+
fileName: error.fileName,
|
|
138
|
+
lineNumber: error.lineNumber,
|
|
139
|
+
message: error.message
|
|
140
|
+
});
|
|
141
|
+
// Alert user: File is corrupt or invalid format
|
|
142
|
+
throw error; // Don't retry
|
|
143
|
+
|
|
144
|
+
} else if (error instanceof PathResolutionError) {
|
|
145
|
+
// Wrong path in mapping config
|
|
146
|
+
logger.error('Path resolution failed:', {
|
|
147
|
+
path: error.path,
|
|
148
|
+
message: error.message
|
|
149
|
+
});
|
|
150
|
+
// Alert developer: Fix mapping configuration
|
|
151
|
+
throw error; // Don't retry
|
|
152
|
+
|
|
153
|
+
} else if (error instanceof MappingError) {
|
|
154
|
+
// Required field missing or type mismatch
|
|
155
|
+
logger.error('Mapping failed:', {
|
|
156
|
+
field: error.field,
|
|
157
|
+
sourcePath: error.sourcePath,
|
|
158
|
+
message: error.message
|
|
159
|
+
});
|
|
160
|
+
// Alert developer: Data doesn't match mapping expectations
|
|
161
|
+
throw error; // Don't retry
|
|
162
|
+
|
|
163
|
+
} else if (error instanceof IngestionError) {
|
|
164
|
+
logger.error('Ingestion error:', error.toJSON());
|
|
165
|
+
|
|
166
|
+
// Retry if transient error
|
|
167
|
+
if (error.isRetryable()) {
|
|
168
|
+
return scheduleRetry();
|
|
169
|
+
}
|
|
170
|
+
throw error; // Non-retryable
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Unknown error
|
|
174
|
+
throw error;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**Key points:**
|
|
180
|
+
- ✅ Checks specific error types with `instanceof`
|
|
181
|
+
- ✅ Logs error-specific context
|
|
182
|
+
- ✅ Uses `error.isRetryable()` for retry decisions
|
|
183
|
+
- ✅ Different handling for different error types
|
|
184
|
+
- ✅ Clear comments explaining each case
|
|
185
|
+
|
|
186
|
+
## Comprehensive Error Handling
|
|
187
|
+
|
|
188
|
+
### Production-Ready Pattern with Retry Logic
|
|
189
|
+
|
|
190
|
+
Complete error handling for production systems:
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
import {
|
|
194
|
+
createClient,
|
|
195
|
+
XMLParserService,
|
|
196
|
+
GraphQLMutationMapper,
|
|
197
|
+
FileParsingError,
|
|
198
|
+
PathResolutionError,
|
|
199
|
+
MappingError,
|
|
200
|
+
ValidationError,
|
|
201
|
+
IngestionError,
|
|
202
|
+
IngestionErrorCode,
|
|
203
|
+
GraphQLExecutionError,
|
|
204
|
+
FluentAPIError
|
|
205
|
+
} from '@fluentcommerce/fc-connect-sdk';
|
|
206
|
+
|
|
207
|
+
async function processOrderWithRetry(
|
|
208
|
+
xmlContent: string,
|
|
209
|
+
maxRetries = 3
|
|
210
|
+
): Promise<any> {
|
|
211
|
+
let attempt = 0;
|
|
212
|
+
|
|
213
|
+
while (attempt < maxRetries) {
|
|
214
|
+
try {
|
|
215
|
+
attempt++;
|
|
216
|
+
|
|
217
|
+
// Parse XML
|
|
218
|
+
const parser = new XMLParserService();
|
|
219
|
+
let parsed;
|
|
220
|
+
|
|
221
|
+
try {
|
|
222
|
+
parsed = await parser.parse(xmlContent);
|
|
223
|
+
} catch (error) {
|
|
224
|
+
if (error instanceof FileParsingError) {
|
|
225
|
+
// Parse error = permanent failure, don't retry
|
|
226
|
+
logger.error('XML parse error (permanent):', {
|
|
227
|
+
code: error.code,
|
|
228
|
+
fileName: error.fileName,
|
|
229
|
+
message: error.message
|
|
230
|
+
});
|
|
231
|
+
throw error; // Don't retry
|
|
232
|
+
}
|
|
233
|
+
throw error;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Map to mutation
|
|
237
|
+
const mapper = new GraphQLMutationMapper(mappingConfig, logger, { fluentClient: client });
|
|
238
|
+
let payload;
|
|
239
|
+
|
|
240
|
+
try {
|
|
241
|
+
payload = await mapper.map(parsed);
|
|
242
|
+
} catch (error) {
|
|
243
|
+
if (error instanceof PathResolutionError) {
|
|
244
|
+
// Wrong path = permanent failure (config issue)
|
|
245
|
+
logger.error('Path error (permanent):', {
|
|
246
|
+
path: error.path,
|
|
247
|
+
message: error.message
|
|
248
|
+
});
|
|
249
|
+
throw error; // Don't retry
|
|
250
|
+
|
|
251
|
+
} else if (error instanceof MappingError) {
|
|
252
|
+
// Mapping error = permanent failure (data/config issue)
|
|
253
|
+
logger.error('Mapping error (permanent):', {
|
|
254
|
+
field: error.field,
|
|
255
|
+
sourcePath: error.sourcePath,
|
|
256
|
+
message: error.message
|
|
257
|
+
});
|
|
258
|
+
throw error; // Don't retry
|
|
259
|
+
}
|
|
260
|
+
throw error;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Execute mutation
|
|
264
|
+
const result = await client.graphql(payload);
|
|
265
|
+
|
|
266
|
+
// Success - return complete data
|
|
267
|
+
return result.data;
|
|
268
|
+
|
|
269
|
+
} catch (error) {
|
|
270
|
+
// Check if error is retryable
|
|
271
|
+
|
|
272
|
+
// 1. GraphQL Execution Error (e.g. Timeout/Network in GraphQL response)
|
|
273
|
+
if (error instanceof GraphQLExecutionError) {
|
|
274
|
+
const graphqlError = error.graphqlErrors[0];
|
|
275
|
+
|
|
276
|
+
if (graphqlError.extensions?.code === 'TIMEOUT' ||
|
|
277
|
+
graphqlError.extensions?.code === 'NETWORK_ERROR') {
|
|
278
|
+
|
|
279
|
+
if (attempt < maxRetries) {
|
|
280
|
+
await delay(1000 * attempt);
|
|
281
|
+
continue; // Retry
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
// Permanent GraphQL error
|
|
285
|
+
throw error;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// 2. Ingestion Error (Network, etc.)
|
|
289
|
+
if (error instanceof IngestionError && error.isRetryable()) {
|
|
290
|
+
if (attempt < maxRetries) {
|
|
291
|
+
logger.warn(`Retryable error, attempt ${attempt}/${maxRetries}`, {
|
|
292
|
+
code: error.code,
|
|
293
|
+
message: error.message
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
// Exponential backoff
|
|
297
|
+
await delay(1000 * Math.pow(2, attempt - 1));
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// 3. Fluent API Error (HTTP 5xx)
|
|
303
|
+
if (error instanceof FluentAPIError && error.statusCode >= 500) {
|
|
304
|
+
if (attempt < maxRetries) {
|
|
305
|
+
await delay(1000 * attempt);
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Non-retryable error or max retries exceeded
|
|
311
|
+
logger.error('Order processing failed:', {
|
|
312
|
+
attempt,
|
|
313
|
+
error: error instanceof IngestionError ? error.toJSON() : error.message
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
throw error;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
throw new Error('Max retries exceeded');
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
function delay(ms: number): Promise<void> {
|
|
324
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
325
|
+
}
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
**Key points:**
|
|
329
|
+
- ✅ Retry loop with max attempts
|
|
330
|
+
- ✅ Specific handling at each stage (parse, map, execute)
|
|
331
|
+
- ✅ Permanent errors immediately thrown (no retry)
|
|
332
|
+
- ✅ Transient errors retried with exponential backoff
|
|
333
|
+
- ✅ GraphQL errors classified by code
|
|
334
|
+
- ✅ Detailed logging at each stage
|
|
335
|
+
|
|
336
|
+
## Error Handling with Monitoring
|
|
337
|
+
|
|
338
|
+
### Adding Metrics Collection
|
|
339
|
+
|
|
340
|
+
Track error patterns for alerting and analysis:
|
|
341
|
+
|
|
342
|
+
```typescript
|
|
343
|
+
import {
|
|
344
|
+
IngestionError,
|
|
345
|
+
IngestionErrorCode,
|
|
346
|
+
MappingError,
|
|
347
|
+
PathResolutionError
|
|
348
|
+
} from '@fluentcommerce/fc-connect-sdk';
|
|
349
|
+
|
|
350
|
+
class ErrorMonitor {
|
|
351
|
+
private errorCounts = new Map<string, number>();
|
|
352
|
+
private lastErrors = new Map<string, Date>();
|
|
353
|
+
|
|
354
|
+
recordError(error: Error): void {
|
|
355
|
+
let errorType = 'UNKNOWN';
|
|
356
|
+
|
|
357
|
+
if (error instanceof IngestionError) {
|
|
358
|
+
errorType = error.code;
|
|
359
|
+
} else if (error instanceof MappingError) {
|
|
360
|
+
errorType = 'MAPPING_ERROR';
|
|
361
|
+
} else if (error instanceof PathResolutionError) {
|
|
362
|
+
errorType = 'PATH_RESOLUTION_ERROR';
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
const count = this.errorCounts.get(errorType) || 0;
|
|
366
|
+
this.errorCounts.set(errorType, count + 1);
|
|
367
|
+
this.lastErrors.set(errorType, new Date());
|
|
368
|
+
|
|
369
|
+
// Alert if error rate is high
|
|
370
|
+
if (count + 1 > 10) {
|
|
371
|
+
this.alertHighErrorRate(errorType, count + 1);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
getMetrics() {
|
|
376
|
+
return {
|
|
377
|
+
errorCounts: Object.fromEntries(this.errorCounts),
|
|
378
|
+
lastErrors: Object.fromEntries(this.lastErrors),
|
|
379
|
+
timestamp: new Date().toISOString()
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
private alertHighErrorRate(errorType: string, count: number): void {
|
|
384
|
+
console.error(`HIGH ERROR RATE: ${errorType} - ${count} errors`);
|
|
385
|
+
// Send alert to monitoring system (PagerDuty, Slack, etc.)
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
const errorMonitor = new ErrorMonitor();
|
|
390
|
+
|
|
391
|
+
async function processWithMonitoring(data: any) {
|
|
392
|
+
try {
|
|
393
|
+
return await processOrder(data);
|
|
394
|
+
} catch (error) {
|
|
395
|
+
errorMonitor.recordError(error);
|
|
396
|
+
throw error;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
**Features:**
|
|
402
|
+
- ✅ Tracks error counts by type
|
|
403
|
+
- ✅ Records last occurrence of each error
|
|
404
|
+
- ✅ Alerts on high error rates
|
|
405
|
+
- ✅ Provides metrics for dashboards
|
|
406
|
+
|
|
407
|
+
### Integration with Monitoring Systems
|
|
408
|
+
|
|
409
|
+
Send errors to external monitoring:
|
|
410
|
+
|
|
411
|
+
```typescript
|
|
412
|
+
import { IngestionError } from '@fluentcommerce/fc-connect-sdk';
|
|
413
|
+
|
|
414
|
+
async function processWithExternalMonitoring(data: any) {
|
|
415
|
+
try {
|
|
416
|
+
return await processOrder(data);
|
|
417
|
+
} catch (error) {
|
|
418
|
+
// Send to monitoring service
|
|
419
|
+
if (error instanceof IngestionError) {
|
|
420
|
+
await sendToDatadog({
|
|
421
|
+
metric: 'ingestion.error',
|
|
422
|
+
tags: [
|
|
423
|
+
`error_code:${error.code}`,
|
|
424
|
+
`retryable:${error.isRetryable()}`
|
|
425
|
+
],
|
|
426
|
+
value: 1
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
await sendToSentry({
|
|
430
|
+
message: error.message,
|
|
431
|
+
level: 'error',
|
|
432
|
+
extra: error.toJSON()
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
throw error;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
async function sendToDatadog(metric: any) {
|
|
441
|
+
// Datadog integration
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
async function sendToSentry(event: any) {
|
|
445
|
+
// Sentry integration
|
|
446
|
+
}
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
## Stage-Specific Error Handling
|
|
450
|
+
|
|
451
|
+
### Parsing Stage
|
|
452
|
+
|
|
453
|
+
Handle parsing errors separately:
|
|
454
|
+
|
|
455
|
+
```typescript
|
|
456
|
+
async function safeParse(content: string, fileName: string): Promise<any> {
|
|
457
|
+
try {
|
|
458
|
+
const parser = new XMLParserService();
|
|
459
|
+
return await parser.parse(content);
|
|
460
|
+
} catch (error) {
|
|
461
|
+
if (error instanceof FileParsingError) {
|
|
462
|
+
logger.error('Parsing failed - permanent error', {
|
|
463
|
+
fileName,
|
|
464
|
+
lineNumber: error.lineNumber,
|
|
465
|
+
code: error.code
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
// Save to dead letter queue for manual review
|
|
469
|
+
await saveToDeadLetterQueue({
|
|
470
|
+
fileName,
|
|
471
|
+
content,
|
|
472
|
+
error: error.toJSON()
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
throw error; // Don't retry
|
|
476
|
+
}
|
|
477
|
+
throw error;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
### Mapping Stage
|
|
483
|
+
|
|
484
|
+
Handle mapping errors with detailed context:
|
|
485
|
+
|
|
486
|
+
```typescript
|
|
487
|
+
async function safeMap(parsed: any, context: any): Promise<any> {
|
|
488
|
+
try {
|
|
489
|
+
const mapper = new GraphQLMutationMapper(mappingConfig, logger, { fluentClient: client });
|
|
490
|
+
return await mapper.map(parsed);
|
|
491
|
+
} catch (error) {
|
|
492
|
+
if (error instanceof MappingError) {
|
|
493
|
+
logger.error('Mapping failed - check data or config', {
|
|
494
|
+
field: error.field,
|
|
495
|
+
sourcePath: error.sourcePath,
|
|
496
|
+
context
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
// Log sample data for debugging
|
|
500
|
+
await logSampleData({
|
|
501
|
+
field: error.field,
|
|
502
|
+
sourcePath: error.sourcePath,
|
|
503
|
+
sourceData: parsed
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
throw error; // Don't retry
|
|
507
|
+
} else if (error instanceof PathResolutionError) {
|
|
508
|
+
logger.error('Path resolution failed - check config', {
|
|
509
|
+
path: error.path,
|
|
510
|
+
availablePaths: Object.keys(parsed)
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
throw error; // Don't retry
|
|
514
|
+
}
|
|
515
|
+
throw error;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
### Execution Stage
|
|
521
|
+
|
|
522
|
+
Handle API errors with retry logic:
|
|
523
|
+
|
|
524
|
+
```typescript
|
|
525
|
+
async function safeExecute(
|
|
526
|
+
payload: any,
|
|
527
|
+
maxRetries = 3
|
|
528
|
+
): Promise<any> {
|
|
529
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
530
|
+
try {
|
|
531
|
+
const result = await client.graphql(payload);
|
|
532
|
+
return result.data;
|
|
533
|
+
|
|
534
|
+
} catch (error) {
|
|
535
|
+
// Check for retryable GraphQL errors
|
|
536
|
+
if (error instanceof GraphQLExecutionError) {
|
|
537
|
+
const firstError = error.graphqlErrors[0];
|
|
538
|
+
if (firstError.extensions?.code === 'TIMEOUT' && attempt < maxRetries) {
|
|
539
|
+
const delay = Math.pow(2, attempt) * 1000;
|
|
540
|
+
logger.warn(`GraphQL timeout, retrying in ${delay}ms`, { attempt });
|
|
541
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
542
|
+
continue;
|
|
543
|
+
}
|
|
544
|
+
throw error;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
if (error instanceof IngestionError &&
|
|
548
|
+
error.isRetryable() &&
|
|
549
|
+
attempt < maxRetries) {
|
|
550
|
+
|
|
551
|
+
const delay = Math.pow(2, attempt) * 1000;
|
|
552
|
+
logger.warn(`Retrying after ${delay}ms`, { attempt, error: error.code });
|
|
553
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
554
|
+
continue;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
throw error;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
throw new Error('Max retries exceeded');
|
|
562
|
+
}
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
## Error Context Enrichment
|
|
566
|
+
|
|
567
|
+
### Adding Context to Errors
|
|
568
|
+
|
|
569
|
+
Enrich errors with business context:
|
|
570
|
+
|
|
571
|
+
```typescript
|
|
572
|
+
async function processOrderWithContext(xmlContent: string, metadata: any) {
|
|
573
|
+
try {
|
|
574
|
+
return await processOrder(xmlContent);
|
|
575
|
+
} catch (error) {
|
|
576
|
+
// Enrich error with business context
|
|
577
|
+
const enrichedError = new Error(error.message);
|
|
578
|
+
enrichedError.cause = error;
|
|
579
|
+
enrichedError.context = {
|
|
580
|
+
...metadata,
|
|
581
|
+
timestamp: new Date().toISOString(),
|
|
582
|
+
environment: process.env.NODE_ENV,
|
|
583
|
+
version: process.env.APP_VERSION
|
|
584
|
+
};
|
|
585
|
+
|
|
586
|
+
if (error instanceof IngestionError) {
|
|
587
|
+
enrichedError.context.errorCode = error.code;
|
|
588
|
+
enrichedError.context.retryable = error.isRetryable();
|
|
589
|
+
enrichedError.context.originalContext = error.context;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
logger.error('Order processing failed with context:', enrichedError.context);
|
|
593
|
+
throw enrichedError;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
## Key Takeaways
|
|
599
|
+
|
|
600
|
+
- 🎯 **Always use try-catch** - Never call SDK methods without error handling
|
|
601
|
+
- 🎯 **Check error types** - Use `instanceof` for specific handling
|
|
602
|
+
- 🎯 **Re-throw errors** - Don't silence failures
|
|
603
|
+
- 🎯 **Log with context** - Include all relevant error details
|
|
604
|
+
- 🎯 **Monitor patterns** - Track error rates for alerting
|
|
605
|
+
- 🎯 **Enrich errors** - Add business context before logging
|
|
606
|
+
|
|
607
|
+
## Practice Exercise
|
|
608
|
+
|
|
609
|
+
Improve this error handling code:
|
|
610
|
+
|
|
611
|
+
```typescript
|
|
612
|
+
// ❌ POOR ERROR HANDLING
|
|
613
|
+
async function processData(data: any) {
|
|
614
|
+
try {
|
|
615
|
+
const result = await client.graphql(query);
|
|
616
|
+
return result.data;
|
|
617
|
+
} catch (error) {
|
|
618
|
+
console.log('Error');
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
<details>
|
|
624
|
+
<summary>Click to see improved version</summary>
|
|
625
|
+
|
|
626
|
+
```typescript
|
|
627
|
+
// ✅ IMPROVED ERROR HANDLING
|
|
628
|
+
import {
|
|
629
|
+
FileParsingError,
|
|
630
|
+
MappingError,
|
|
631
|
+
IngestionError
|
|
632
|
+
} from '@fluentcommerce/fc-connect-sdk';
|
|
633
|
+
|
|
634
|
+
async function processData(data: any, context: any) {
|
|
635
|
+
try {
|
|
636
|
+
const result = await client.graphql(query);
|
|
637
|
+
|
|
638
|
+
if (result.errors) {
|
|
639
|
+
throw new Error(`GraphQL error: ${result.errors[0].message}`);
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
return result.data;
|
|
643
|
+
|
|
644
|
+
} catch (error) {
|
|
645
|
+
// Log with full context
|
|
646
|
+
logger.error('Data processing failed:', {
|
|
647
|
+
context,
|
|
648
|
+
error: error instanceof IngestionError ? error.toJSON() : error.message
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
// Check if retryable
|
|
652
|
+
if (error instanceof IngestionError && error.isRetryable()) {
|
|
653
|
+
return scheduleRetry(data, context);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
// Re-throw for upstream handling
|
|
657
|
+
throw error;
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
</details>
|
|
663
|
+
|
|
664
|
+
## Next Steps
|
|
665
|
+
|
|
666
|
+
Continue to [Module 6: Retry Strategies →](./error-handling-06-retry-strategies.md) to learn advanced retry patterns with exponential backoff.
|
|
667
|
+
|
|
668
|
+
---
|
|
669
|
+
|
|
670
|
+
**Previous:** [← Module 4: Error Scenarios](./error-handling-04-error-scenarios.md)
|
|
671
|
+
**Next:** [Module 6: Retry Strategies →](./error-handling-06-retry-strategies.md)
|