@fluentcommerce/fc-connect-sdk 0.1.54 → 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 +12 -0
- package/dist/cjs/clients/fluent-client.js +13 -6
- package/dist/cjs/utils/pagination-helpers.js +38 -2
- package/dist/cjs/versori/fluent-versori-client.js +11 -5
- package/dist/esm/clients/fluent-client.js +13 -6
- package/dist/esm/utils/pagination-helpers.js +38 -2
- package/dist/esm/versori/fluent-versori-client.js +11 -5
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/tsconfig.types.tsbuildinfo +1 -1
- package/docs/00-START-HERE/EXPORT-VALIDATION.md +158 -158
- package/docs/00-START-HERE/cli-analyze-source-structure-guide.md +655 -655
- package/docs/00-START-HERE/cli-documentation-index.md +202 -202
- package/docs/00-START-HERE/cli-quick-reference.md +252 -252
- package/docs/00-START-HERE/decision-tree.md +552 -552
- package/docs/00-START-HERE/getting-started.md +1070 -1070
- package/docs/00-START-HERE/mapper-quick-decision-guide.md +235 -235
- package/docs/00-START-HERE/readme.md +237 -237
- package/docs/00-START-HERE/retailerid-configuration.md +404 -404
- package/docs/00-START-HERE/sdk-philosophy.md +794 -794
- package/docs/00-START-HERE/troubleshooting-quick-reference.md +1086 -1086
- package/docs/01-TEMPLATES/faq.md +686 -686
- package/docs/01-TEMPLATES/patterns/pattern-templates-guide.md +68 -68
- package/docs/01-TEMPLATES/patterns/patterns-csv-schema-validation-and-rejection-report.md +233 -233
- package/docs/01-TEMPLATES/patterns/patterns-custom-resolvers.md +407 -407
- package/docs/01-TEMPLATES/patterns/patterns-error-handling-retry.md +511 -511
- package/docs/01-TEMPLATES/patterns/patterns-field-mapping-universal.md +701 -701
- package/docs/01-TEMPLATES/patterns/patterns-large-file-splitting.md +1430 -1430
- package/docs/01-TEMPLATES/patterns/patterns-master-data-etl.md +2399 -2399
- package/docs/01-TEMPLATES/patterns/patterns-pagination-streaming.md +447 -447
- package/docs/01-TEMPLATES/patterns/patterns-state-duplicate-prevention.md +385 -385
- package/docs/01-TEMPLATES/readme.md +957 -957
- package/docs/01-TEMPLATES/standalone/standalone-asn-inbound-processing.md +1209 -1209
- package/docs/01-TEMPLATES/standalone/standalone-graphql-query-export.md +1140 -1140
- package/docs/01-TEMPLATES/standalone/standalone-graphql-to-parquet-partitioned-s3.md +432 -432
- package/docs/01-TEMPLATES/standalone/standalone-multi-channel-inventory-sync.md +1185 -1185
- package/docs/01-TEMPLATES/standalone/standalone-multi-source-aggregation.md +1462 -1462
- package/docs/01-TEMPLATES/standalone/standalone-s3-csv-batch-api.md +1390 -1390
- package/docs/01-TEMPLATES/standalone/standalone-s3-csv-inventory-to-batch.md +330 -330
- package/docs/01-TEMPLATES/standalone/standalone-scripts-guide.md +87 -87
- package/docs/01-TEMPLATES/standalone/standalone-sftp-xml-graphql.md +1444 -1444
- package/docs/01-TEMPLATES/standalone/standalone-webhook-payload-processing.md +688 -688
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-dropship-order-routing.md +193 -193
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-graphql-parquet-extraction.md +518 -518
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-inter-location-transfers.md +2162 -2162
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-pre-order-allocation.md +2226 -2226
- package/docs/01-TEMPLATES/versori/business-examples/business-scenarios-guide.md +87 -87
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-connection-validation-pattern.md +656 -656
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-dual-workflow-connector.md +835 -835
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-guide.md +108 -108
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-kv-state-management.md +1533 -1533
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-xml-response-patterns.md +1160 -1160
- package/docs/01-TEMPLATES/versori/versori-platform-guide.md +201 -201
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-asn-purchase-order.md +1906 -1906
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-dropship-routing.md +1074 -1074
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-flash-sale-reserve.md +1395 -1395
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-generic-xml-order.md +888 -888
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-payment-gateway-integration.md +2478 -2478
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-rma-returns-comprehensive.md +2240 -2240
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-xml-order-ingestion.md +2029 -2029
- package/docs/01-TEMPLATES/versori/webhooks/webhook-templates-guide.md +140 -140
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/inventory-mapping.json +20 -20
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/products_2025-01-22.csv +11 -11
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/sample-data-guide.md +34 -34
- package/docs/01-TEMPLATES/versori/workflows/_examples/workflow-examples-guide.md +36 -36
- package/docs/01-TEMPLATES/versori/workflows/extraction/extraction-modes-guide.md +1038 -1038
- package/docs/01-TEMPLATES/versori/workflows/extraction/extraction-workflows-guide.md +138 -138
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/graphql-extraction-guide.md +63 -63
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-fulfillments-to-sftp-csv.md +2062 -2062
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-fulfillments-to-sftp-xml.md +2294 -2294
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-positions-to-s3-csv.md +2461 -2461
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-positions-to-sftp-xml.md +2529 -2529
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-quantities-to-s3-csv.md +2464 -2464
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-quantities-to-s3-json.md +1959 -1959
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-orders-to-s3-csv.md +1953 -1953
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-orders-to-sftp-xml.md +2541 -2541
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-products-to-s3-json.md +2384 -2384
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-products-to-sftp-xml.md +2445 -2445
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-s3-csv.md +2355 -2355
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-s3-json.md +2042 -2042
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-sftp-xml.md +2726 -2726
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/batch-api-guide.md +206 -206
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-cycle-count-reconciliation.md +2030 -2030
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-multi-channel-inventory-sync.md +1882 -1882
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-csv-inventory-batch.md +2827 -2827
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-json-inventory-batch.md +1952 -1952
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-xml-inventory-batch.md +3289 -3289
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-csv-inventory-batch.md +3064 -3064
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-json-inventory-batch.md +3238 -3238
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-xml-inventory-batch.md +2977 -2977
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/event-api-guide.md +321 -321
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-payload-json-order-cancel-event.md +959 -959
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-payload-xml-order-cancel-event.md +1170 -1170
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-csv-product-event.md +2312 -2312
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-json-product-event.md +2999 -2999
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-parquet-product-event.md +2836 -2836
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-xml-product-event.md +2395 -2395
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-csv-product-event.md +2295 -2295
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-json-product-event.md +2602 -2602
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-parquet-product-event.md +2589 -2589
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-xml-product-event.md +3578 -3578
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/graphql-mutations-guide.md +93 -93
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-payload-json-order-update-graphql.md +1260 -1260
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-payload-xml-order-update-graphql.md +1472 -1472
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-control-graphql.md +2417 -2417
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-location-graphql.md +2811 -2811
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-price-graphql.md +2619 -2619
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-json-location-graphql.md +2807 -2807
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-xml-location-graphql.md +2373 -2373
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-csv-control-graphql.md +2740 -2740
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-csv-location-graphql.md +2760 -2760
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-json-location-graphql.md +1710 -1710
- package/docs/01-TEMPLATES/versori/workflows/ingestion/ingestion-workflows-guide.md +136 -136
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/rubix-webhooks-guide.md +520 -520
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-fulfilment-to-sftp-xml-inline.md +1418 -1418
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-fulfilment-to-sftp-xml-universal-mapper.md +1785 -1785
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-order-attribute-update.md +824 -824
- package/docs/01-TEMPLATES/versori/workflows/workflows-overview-guide.md +646 -646
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-batch-archival.md +724 -724
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-job-tracker.md +627 -627
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-partial-batch-recovery.md +561 -561
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-quick-reference.md +367 -367
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-readme.md +407 -407
- package/docs/02-CORE-GUIDES/advanced-services/readme.md +49 -49
- package/docs/02-CORE-GUIDES/api-reference/api-reference-quick-reference.md +548 -548
- package/docs/02-CORE-GUIDES/api-reference/event-api-input-output-reference.md +702 -1171
- package/docs/02-CORE-GUIDES/api-reference/examples/client-initialization.ts +286 -286
- package/docs/02-CORE-GUIDES/api-reference/graphql-error-classification.md +337 -337
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-01-client-api.md +399 -520
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-03-authentication.md +199 -199
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-04-graphql-mapping.md +925 -925
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-05-services.md +1198 -1198
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-06-data-sources.md +1083 -1083
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-07-parsers.md +1097 -1097
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-08-pagination.md +513 -513
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-08-types.md +545 -597
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-09-error-handling.md +527 -527
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-09-webhook-validation.md +514 -514
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-10-extraction.md +557 -557
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-10-utilities.md +412 -412
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-11-cli-tools.md +423 -423
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-11-error-handling.md +716 -716
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-analyze-source-structure.md +518 -518
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-partial-responses.md +212 -212
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-testing.md +300 -300
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-13-resolver-builder.md +322 -322
- package/docs/02-CORE-GUIDES/api-reference/readme.md +279 -279
- package/docs/02-CORE-GUIDES/auto-pagination/auto-pagination-quick-reference.md +351 -351
- package/docs/02-CORE-GUIDES/auto-pagination/auto-pagination-readme.md +277 -277
- package/docs/02-CORE-GUIDES/auto-pagination/examples/auto-pagination-readme.md +178 -178
- package/docs/02-CORE-GUIDES/auto-pagination/examples/common-patterns.ts +351 -351
- package/docs/02-CORE-GUIDES/auto-pagination/examples/paginate-products.ts +384 -384
- package/docs/02-CORE-GUIDES/auto-pagination/examples/paginate-virtual-positions.ts +308 -308
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-01-foundations.md +470 -470
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-02-quick-start.md +713 -713
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-03-configuration.md +754 -754
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-04-advanced-patterns.md +732 -732
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-05-sdk-integration.md +847 -847
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-06-troubleshooting.md +359 -359
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-07-api-reference.md +462 -462
- package/docs/02-CORE-GUIDES/auto-pagination/readme.md +54 -54
- package/docs/02-CORE-GUIDES/data-sources/data-sources-file-operations-error-handling.md +1487 -1487
- package/docs/02-CORE-GUIDES/data-sources/data-sources-quick-reference.md +836 -836
- package/docs/02-CORE-GUIDES/data-sources/data-sources-readme.md +276 -276
- package/docs/02-CORE-GUIDES/data-sources/data-sources-sftp-credential-access-security.md +553 -553
- package/docs/02-CORE-GUIDES/data-sources/examples/common-patterns.ts +409 -409
- package/docs/02-CORE-GUIDES/data-sources/examples/data-sources-readme.md +178 -178
- package/docs/02-CORE-GUIDES/data-sources/examples/s3-operations.ts +308 -308
- package/docs/02-CORE-GUIDES/data-sources/examples/sftp-operations.ts +371 -371
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-01-foundations.md +735 -735
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-02-s3-operations.md +1302 -1302
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-03-sftp-operations.md +1379 -1379
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-04-file-patterns.md +941 -941
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-05-advanced-topics.md +813 -813
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-06-integration-patterns.md +486 -486
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-07-troubleshooting.md +387 -387
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-08-api-reference.md +417 -417
- package/docs/02-CORE-GUIDES/data-sources/readme.md +77 -77
- package/docs/02-CORE-GUIDES/error-handling-guide.md +936 -936
- package/docs/02-CORE-GUIDES/extraction/examples/02-core-guides-extraction-readme.md +116 -116
- package/docs/02-CORE-GUIDES/extraction/examples/common-patterns.ts +428 -428
- package/docs/02-CORE-GUIDES/extraction/examples/extract-inventory-basic.ts +187 -187
- package/docs/02-CORE-GUIDES/extraction/extraction-quick-reference.md +596 -596
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-01-foundations.md +514 -514
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-02-basic-extraction.md +823 -823
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-03-parquet-processing.md +507 -507
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-04-data-enrichment.md +546 -546
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-05-transformation.md +494 -494
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-06-export-formats.md +458 -458
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-06-performance.md +138 -138
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-07-api-reference.md +148 -148
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-07-optimization.md +692 -692
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-08-extraction-orchestrator.md +1008 -1008
- package/docs/02-CORE-GUIDES/extraction/readme.md +151 -151
- package/docs/02-CORE-GUIDES/ingestion/examples/_simple-kv-store.ts +40 -40
- package/docs/02-CORE-GUIDES/ingestion/examples/error-recovery.ts +728 -728
- package/docs/02-CORE-GUIDES/ingestion/examples/event-driven.ts +501 -501
- package/docs/02-CORE-GUIDES/ingestion/examples/local-file-ingestion.ts +88 -88
- package/docs/02-CORE-GUIDES/ingestion/examples/parquet-ingestion.ts +117 -117
- package/docs/02-CORE-GUIDES/ingestion/examples/performance-optimized.ts +647 -647
- package/docs/02-CORE-GUIDES/ingestion/examples/s3-csv-ingestion.ts +169 -169
- package/docs/02-CORE-GUIDES/ingestion/examples/sftp-csv-ingestion.ts +134 -134
- package/docs/02-CORE-GUIDES/ingestion/ingestion-quick-reference.md +546 -546
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-01-introduction.md +626 -626
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-02-quick-start.md +658 -658
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-03-data-sources.md +1052 -1052
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-04-field-mapping.md +763 -763
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-05-advanced-parsers.md +676 -676
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-06-batch-api.md +1295 -1295
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-07-api-reference.md +138 -138
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-07-state-management.md +1037 -1037
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-08-performance-optimization.md +1349 -1349
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-09-best-practices.md +1893 -1893
- package/docs/02-CORE-GUIDES/ingestion/readme.md +160 -160
- package/docs/02-CORE-GUIDES/logging-guide.md +585 -585
- package/docs/02-CORE-GUIDES/mapping/error-handling-patterns.md +401 -401
- package/docs/02-CORE-GUIDES/mapping/examples/02-core-guides-mapping-readme.md +128 -128
- package/docs/02-CORE-GUIDES/mapping/examples/common-patterns.ts +273 -273
- package/docs/02-CORE-GUIDES/mapping/examples/csv-location-ingestion.json +36 -36
- package/docs/02-CORE-GUIDES/mapping/examples/csv-mapping.ts +242 -242
- package/docs/02-CORE-GUIDES/mapping/examples/graphql-to-parquet-extraction.json +36 -36
- package/docs/02-CORE-GUIDES/mapping/examples/json-mapping.ts +213 -213
- package/docs/02-CORE-GUIDES/mapping/examples/json-product-to-mutation.json +48 -48
- package/docs/02-CORE-GUIDES/mapping/examples/xml-mapping.ts +291 -291
- package/docs/02-CORE-GUIDES/mapping/examples/xml-order-to-mutation.json +45 -45
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/graphql-mutation-mapping-quick-reference.md +463 -463
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/graphql-mutation-mapping-readme.md +227 -227
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-01-introduction.md +222 -222
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-02-quick-start.md +351 -351
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-03-schema-validation.md +569 -569
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-04-mapping-patterns.md +471 -471
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-05-configuration-reference.md +611 -611
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-06-advanced-xpath.md +148 -148
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-06-path-syntax.md +464 -464
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-07-api-reference.md +94 -94
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-07-array-handling.md +307 -307
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-08-custom-resolvers.md +544 -544
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-09-advanced-patterns.md +427 -427
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-10-hooks-and-variables.md +336 -336
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-11-error-handling.md +488 -488
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-12-arguments-vs-nodes.md +383 -383
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-13-best-practices.md +477 -477
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/readme.md +62 -62
- package/docs/02-CORE-GUIDES/mapping/mapping-format-decision-tree.md +480 -480
- package/docs/02-CORE-GUIDES/mapping/mapping-graphql-alias-batching-guide.md +820 -820
- package/docs/02-CORE-GUIDES/mapping/mapping-javascript-objects.md +2369 -2369
- package/docs/02-CORE-GUIDES/mapping/mapping-mapper-comparison-guide.md +682 -682
- package/docs/02-CORE-GUIDES/mapping/modules/02-core-guides-mapping-07-api-reference.md +1327 -1327
- package/docs/02-CORE-GUIDES/mapping/modules/02-core-guides-mapping-08-error-handling.md +1142 -1142
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-04-use-cases.md +891 -891
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-06-helpers-resolvers.md +1126 -1126
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-06-sdk-resolvers.md +199 -199
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-07-api-reference.md +1319 -1319
- package/docs/02-CORE-GUIDES/mapping/readme.md +178 -178
- package/docs/02-CORE-GUIDES/mapping/resolver-registration.md +410 -410
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/common-patterns.ts +226 -226
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/custom-resolvers.ts +227 -227
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/sdk-resolvers-usage.ts +203 -203
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-readme.md +274 -274
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-api-reference.md +679 -679
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-cookbook.md +826 -826
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-guide.md +1330 -1330
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-helpers-reference.md +1437 -1437
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-parameters-reference.md +553 -553
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-troubleshooting.md +854 -854
- package/docs/02-CORE-GUIDES/mapping/resolvers/readme.md +75 -75
- package/docs/02-CORE-GUIDES/parsers/examples/02-core-guides-parsers-readme.md +161 -161
- package/docs/02-CORE-GUIDES/parsers/examples/csv-parser-examples.ts +110 -110
- package/docs/02-CORE-GUIDES/parsers/examples/json-parser-examples.ts +33 -33
- package/docs/02-CORE-GUIDES/parsers/examples/parquet-parser-examples.ts +47 -47
- package/docs/02-CORE-GUIDES/parsers/examples/xml-parser-examples.ts +38 -38
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-01-foundations.md +355 -355
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-02-csv-parser.md +772 -772
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-03-json-parser.md +789 -789
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-04-xml-parser.md +857 -857
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-05-parquet-parser.md +603 -603
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-06-integration-patterns.md +702 -702
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-06-streaming.md +121 -121
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-07-api-reference.md +89 -89
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-07-troubleshooting.md +727 -727
- package/docs/02-CORE-GUIDES/parsers/parsers-quick-reference.md +482 -482
- package/docs/02-CORE-GUIDES/parsers/parsers-readme.md +258 -258
- package/docs/02-CORE-GUIDES/parsers/readme.md +65 -65
- package/docs/02-CORE-GUIDES/readme.md +194 -194
- package/docs/02-CORE-GUIDES/webhook-validation/examples/basic-validation.ts +108 -108
- package/docs/02-CORE-GUIDES/webhook-validation/examples/common-patterns.ts +316 -316
- package/docs/02-CORE-GUIDES/webhook-validation/examples/webhook-validation-readme.md +61 -61
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-01-foundations.md +440 -440
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-02-quick-start.md +525 -525
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-03-versori-integration.md +741 -741
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-04-platform-integration.md +629 -629
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-05-configuration.md +535 -535
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-06-error-handling.md +611 -611
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-06-troubleshooting.md +124 -124
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-07-api-reference.md +511 -511
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-08-rubix-webhooks.md +590 -590
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-09-rubix-event-vs-http-call.md +432 -432
- package/docs/02-CORE-GUIDES/webhook-validation/readme.md +239 -239
- package/docs/02-CORE-GUIDES/webhook-validation/webhook-validation-quick-reference.md +392 -392
- package/docs/03-PATTERN-GUIDES/connector-scenarios/connector-scenarios-quick-reference.md +498 -498
- package/docs/03-PATTERN-GUIDES/connector-scenarios/connector-scenarios-readme.md +313 -313
- package/docs/03-PATTERN-GUIDES/connector-scenarios/examples/common-patterns.ts +612 -612
- package/docs/03-PATTERN-GUIDES/connector-scenarios/examples/connector-scenarios-readme.md +253 -253
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-01-foundations.md +452 -452
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-02-simple-scenarios.md +681 -681
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-03-intermediate-scenarios.md +637 -637
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-04-advanced-scenarios.md +650 -650
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-05-bidirectional-sync.md +233 -233
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-06-production-patterns.md +442 -442
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-07-reference.md +445 -445
- package/docs/03-PATTERN-GUIDES/connector-scenarios/readme.md +31 -31
- package/docs/03-PATTERN-GUIDES/enterprise-integration-patterns.md +1528 -1528
- package/docs/03-PATTERN-GUIDES/error-handling/comprehensive-error-handling-guide.md +1437 -1437
- package/docs/03-PATTERN-GUIDES/error-handling/error-handling-quick-reference.md +390 -390
- package/docs/03-PATTERN-GUIDES/error-handling/examples/common-patterns.ts +438 -438
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-01-foundations.md +362 -362
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-02-error-types.md +850 -850
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-03-utf8-handling.md +456 -456
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-04-error-scenarios.md +658 -658
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-05-calling-patterns.md +671 -671
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-06-retry-strategies.md +1034 -1034
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-07-monitoring.md +653 -653
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-08-api-reference.md +847 -847
- package/docs/03-PATTERN-GUIDES/error-handling/readme.md +36 -36
- package/docs/03-PATTERN-GUIDES/examples/__tests__/readme.md +40 -40
- package/docs/03-PATTERN-GUIDES/examples/__tests__/resolver-examples.test.js +282 -282
- package/docs/03-PATTERN-GUIDES/examples/test-data/03-pattern-guides-readme.md +110 -110
- package/docs/03-PATTERN-GUIDES/examples/test-data/canonical-inventory.json +123 -123
- package/docs/03-PATTERN-GUIDES/examples/test-data/canonical-order.json +171 -171
- package/docs/03-PATTERN-GUIDES/examples/test-data/readme.md +28 -28
- package/docs/03-PATTERN-GUIDES/extraction/extraction-readme.md +15 -15
- package/docs/03-PATTERN-GUIDES/extraction/readme.md +25 -25
- package/docs/03-PATTERN-GUIDES/file-operations/examples/common-patterns.ts +407 -407
- package/docs/03-PATTERN-GUIDES/file-operations/examples/file-operations-readme.md +142 -142
- package/docs/03-PATTERN-GUIDES/file-operations/file-operations-quick-reference.md +462 -462
- package/docs/03-PATTERN-GUIDES/file-operations/file-operations-readme.md +379 -379
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-01-foundations.md +430 -430
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-02-quick-start.md +484 -484
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-03-s3-operations.md +507 -507
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-04-sftp-operations.md +963 -963
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-05-streaming-performance.md +503 -503
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-06-archive-patterns.md +386 -386
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-06-error-handling.md +117 -117
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-07-api-reference.md +78 -78
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-07-testing-troubleshooting.md +567 -567
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-08-api-reference.md +1055 -1055
- package/docs/03-PATTERN-GUIDES/file-operations/readme.md +32 -32
- package/docs/03-PATTERN-GUIDES/ingestion/ingestion-readme.md +15 -15
- package/docs/03-PATTERN-GUIDES/ingestion/readme.md +25 -25
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/batch-processing.ts +130 -130
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/common-patterns.ts +360 -360
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/delta-sync.ts +130 -130
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/integration-patterns-readme.md +100 -100
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/real-time-webhook.ts +398 -398
- package/docs/03-PATTERN-GUIDES/integration-patterns/integration-patterns-quick-reference.md +962 -962
- package/docs/03-PATTERN-GUIDES/integration-patterns/integration-patterns-readme.md +134 -134
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-01-real-time-processing.md +991 -991
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-02-batch-processing.md +1547 -1547
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-03-delta-sync.md +1108 -1108
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-04-webhook-patterns.md +1181 -1181
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-05-error-handling.md +1061 -1061
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-06-advanced-integration-services.md +1547 -1547
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-06-performance.md +109 -109
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-07-api-reference.md +34 -34
- package/docs/03-PATTERN-GUIDES/integration-patterns/readme.md +30 -30
- package/docs/03-PATTERN-GUIDES/logging-minimal-mode.md +128 -128
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/common-patterns.ts +380 -380
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/multiple-connections-readme.md +139 -139
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/parallel-root-connections.ts +149 -149
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/real-world-scenarios.ts +405 -405
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-01-foundations.md +378 -378
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-02-quick-start.md +566 -566
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-03-targeting-connections.md +659 -659
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-04-parallel-queries.md +656 -656
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-05-best-practices.md +624 -624
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-06-api-reference.md +824 -824
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-06-versori.md +119 -119
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-07-api-reference.md +87 -87
- package/docs/03-PATTERN-GUIDES/multiple-connections/multiple-connections-quick-reference.md +353 -353
- package/docs/03-PATTERN-GUIDES/multiple-connections/multiple-connections-readme.md +270 -270
- package/docs/03-PATTERN-GUIDES/multiple-connections/readme.md +30 -30
- package/docs/03-PATTERN-GUIDES/pagination/pagination-readme.md +14 -14
- package/docs/03-PATTERN-GUIDES/pagination/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/parquet/examples/common-patterns.ts +180 -180
- package/docs/03-PATTERN-GUIDES/parquet/examples/read-parquet.ts +48 -48
- package/docs/03-PATTERN-GUIDES/parquet/examples/write-parquet.ts +65 -65
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-01-introduction.md +393 -393
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-02-quick-start.md +572 -572
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-03-reading-parquet.md +525 -525
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-04-writing-parquet.md +554 -554
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-05-graphql-extraction.md +405 -405
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-06-performance.md +104 -104
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-06-s3-integration.md +511 -511
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-07-api-reference.md +90 -90
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-07-performance-optimization.md +525 -525
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-08-best-practices.md +712 -712
- package/docs/03-PATTERN-GUIDES/parquet/parquet-quick-reference.md +683 -683
- package/docs/03-PATTERN-GUIDES/parquet/parquet-readme.md +248 -248
- package/docs/03-PATTERN-GUIDES/parquet/readme.md +32 -32
- package/docs/03-PATTERN-GUIDES/parsers/parsers-readme.md +12 -12
- package/docs/03-PATTERN-GUIDES/parsers/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/readme.md +159 -159
- package/docs/03-PATTERN-GUIDES/webhooks/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/webhooks/webhooks-readme.md +8 -8
- package/docs/04-REFERENCE/architecture/architecture-01-overview.md +427 -427
- package/docs/04-REFERENCE/architecture/architecture-02-client-architecture.md +424 -424
- package/docs/04-REFERENCE/architecture/architecture-03-data-flow.md +690 -690
- package/docs/04-REFERENCE/architecture/architecture-04-service-layer.md +834 -834
- package/docs/04-REFERENCE/architecture/architecture-05-integration-architecture.md +655 -655
- package/docs/04-REFERENCE/architecture/architecture-06-state-management.md +653 -653
- package/docs/04-REFERENCE/architecture/architecture-adding-new-data-sources.md +686 -686
- package/docs/04-REFERENCE/architecture/readme.md +279 -279
- package/docs/04-REFERENCE/platforms/deno/readme.md +117 -117
- package/docs/04-REFERENCE/platforms/nodejs/readme.md +146 -146
- package/docs/04-REFERENCE/platforms/readme.md +135 -135
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-01-introduction.md +398 -398
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-02-quick-start.md +560 -560
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-03-authentication.md +757 -757
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-04-workflows.md +2476 -2476
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-05-connections.md +1167 -1167
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-06-kv-storage.md +990 -990
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-06-state-management.md +121 -121
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-07-api-reference.md +68 -68
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-07-deployment.md +731 -731
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-08-best-practices.md +1111 -1111
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-09-signature-reference.md +766 -766
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-readme.md +299 -299
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-s3-sftp-configuration-guide.md +1425 -1425
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-webhook-api-key-security.md +816 -816
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-webhook-connection-security.md +681 -681
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-workflow-task-types.md +708 -708
- package/docs/04-REFERENCE/platforms/versori/readme.md +108 -108
- package/docs/04-REFERENCE/readme.md +148 -148
- package/docs/04-REFERENCE/resolver-signature/examples/advanced-resolvers.ts +482 -482
- package/docs/04-REFERENCE/resolver-signature/examples/async-resolvers.ts +496 -496
- package/docs/04-REFERENCE/resolver-signature/examples/basic-resolvers.ts +343 -343
- package/docs/04-REFERENCE/resolver-signature/examples/resolver-signature-readme.md +188 -188
- package/docs/04-REFERENCE/resolver-signature/examples/testing-resolvers.ts +463 -463
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-01-foundations.md +286 -286
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-02-parameter-reference.md +643 -643
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-03-basic-examples.md +521 -521
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-04-advanced-patterns.md +739 -739
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-05-sdk-resolvers.md +531 -531
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-06-migration-guide.md +650 -650
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-06-testing.md +125 -125
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-07-api-reference.md +794 -794
- package/docs/04-REFERENCE/resolver-signature/readme.md +64 -64
- package/docs/04-REFERENCE/resolver-signature/resolver-signature-quick-reference.md +270 -270
- package/docs/04-REFERENCE/resolver-signature/resolver-signature-readme.md +351 -351
- package/docs/04-REFERENCE/schema/fluent-commerce-schema.json +764 -764
- package/docs/04-REFERENCE/schema/readme.md +141 -141
- package/docs/04-REFERENCE/testing/examples/04-reference-testing-readme.md +158 -158
- package/docs/04-REFERENCE/testing/examples/fluent-testing.ts +62 -62
- package/docs/04-REFERENCE/testing/examples/health-check.ts +155 -155
- package/docs/04-REFERENCE/testing/examples/integration-test.ts +119 -119
- package/docs/04-REFERENCE/testing/examples/performance-test.ts +183 -183
- package/docs/04-REFERENCE/testing/examples/s3-testing.ts +127 -127
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-01-foundations.md +267 -267
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-02-s3-testing.md +599 -599
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-03-fluent-testing.md +589 -589
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-04-integration-testing.md +699 -699
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-05-debugging.md +478 -478
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-06-cicd-integration.md +463 -463
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-06-preflight-validation.md +131 -131
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-07-best-practices.md +499 -499
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-07-coverage-ci.md +165 -165
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-08-api-reference.md +634 -634
- package/docs/04-REFERENCE/testing/readme.md +86 -86
- package/docs/04-REFERENCE/testing/testing-quick-reference.md +667 -667
- package/docs/04-REFERENCE/testing/testing-readme.md +286 -286
- package/docs/04-REFERENCE/troubleshooting/readme.md +144 -144
- package/docs/04-REFERENCE/troubleshooting/troubleshooting-deno-sftp-compatibility.md +392 -392
- package/docs/template-loading-matrix.md +242 -242
- package/package.json +5 -3
- package/docs/02-CORE-GUIDES/api-reference/cli-profile-integration.md +0 -377
|
@@ -1,850 +1,850 @@
|
|
|
1
|
-
# Module 2: Error Types & Codes
|
|
2
|
-
|
|
3
|
-
**Level:** Beginner
|
|
4
|
-
**Estimated Time:** 20 minutes
|
|
5
|
-
|
|
6
|
-
## Overview
|
|
7
|
-
|
|
8
|
-
This module provides a complete reference to all error types and error codes in the SDK, including the error class hierarchy and when each error is thrown.
|
|
9
|
-
|
|
10
|
-
## Learning Objectives
|
|
11
|
-
|
|
12
|
-
By the end of this module, you will:
|
|
13
|
-
- ✅ Understand the error class hierarchy
|
|
14
|
-
- ✅ Know all available error codes and their meanings
|
|
15
|
-
- ✅ Recognize which error class is thrown for each scenario
|
|
16
|
-
- ✅ Use `instanceof` checks to handle specific error types
|
|
17
|
-
|
|
18
|
-
## Error Class Hierarchy
|
|
19
|
-
|
|
20
|
-
```
|
|
21
|
-
Error (JavaScript base class)
|
|
22
|
-
│
|
|
23
|
-
├── IngestionError (Ingestion base class)
|
|
24
|
-
│ ├── FileDiscoveryError
|
|
25
|
-
│ ├── FileParsingError
|
|
26
|
-
│ ├── TransformationError
|
|
27
|
-
│ ├── BatchSubmissionError
|
|
28
|
-
│ ├── ConfigurationError
|
|
29
|
-
│ ├── ValidationError
|
|
30
|
-
│ ├── GraphQLExecutionError
|
|
31
|
-
│ └── AggregateIngestionError
|
|
32
|
-
│
|
|
33
|
-
├── FluentError (Base SDK error class - used by services)
|
|
34
|
-
│ ├── FluentAPIError (HTTP errors from Fluent API)
|
|
35
|
-
│ ├── AuthenticationError (401 Unauthorized)
|
|
36
|
-
│ ├── FluentValidationError (Client-side validation)
|
|
37
|
-
│ ├── DataSourceError (S3/SFTP data source errors)
|
|
38
|
-
│ └── WebhookValidationError (Webhook signature validation errors)
|
|
39
|
-
│
|
|
40
|
-
├── MappingError (Field mapping errors - standalone)
|
|
41
|
-
│
|
|
42
|
-
├── ResolverError (Resolver transformation errors - standalone)
|
|
43
|
-
│
|
|
44
|
-
└── PathResolutionError (Path resolution errors - standalone)
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
**Key Points:**
|
|
48
|
-
- `IngestionError` is the base class for all ingestion-related errors
|
|
49
|
-
- `PathResolutionError`, `MappingError`, and `ResolverError` do NOT extend `IngestionError` - they are standalone error classes
|
|
50
|
-
- `FluentError` is used by SDK services (S3, SFTP, webhooks) - separate from ingestion errors
|
|
51
|
-
|
|
52
|
-
### Base Classes
|
|
53
|
-
|
|
54
|
-
#### IngestionError (SDK Base)
|
|
55
|
-
|
|
56
|
-
The base class for all ingestion-related errors:
|
|
57
|
-
|
|
58
|
-
```typescript
|
|
59
|
-
class IngestionError extends Error {
|
|
60
|
-
readonly code: IngestionErrorCode;
|
|
61
|
-
readonly context?: Record<string, any>;
|
|
62
|
-
readonly timestamp: Date;
|
|
63
|
-
readonly correlationId?: string;
|
|
64
|
-
|
|
65
|
-
toJSON(): Record<string, any>;
|
|
66
|
-
isRetryable(): boolean;
|
|
67
|
-
}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
**Key features:**
|
|
71
|
-
- `code`: Machine-readable error code for programmatic handling
|
|
72
|
-
- `context`: Additional error context (file name, record index, etc.)
|
|
73
|
-
- `timestamp`: When the error occurred
|
|
74
|
-
- `correlationId`: For tracking errors across distributed systems
|
|
75
|
-
- `toJSON()`: Serialize error for logging/monitoring
|
|
76
|
-
- `isRetryable()`: Check if error should be retried
|
|
77
|
-
|
|
78
|
-
**Usage:**
|
|
79
|
-
|
|
80
|
-
```typescript
|
|
81
|
-
try {
|
|
82
|
-
await processFile(fileName);
|
|
83
|
-
} catch (error) {
|
|
84
|
-
if (error instanceof IngestionError) {
|
|
85
|
-
console.log('Error code:', error.code);
|
|
86
|
-
console.log('Error JSON:', error.toJSON());
|
|
87
|
-
console.log('Can retry?', error.isRetryable());
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
## Error Codes Reference
|
|
93
|
-
|
|
94
|
-
### File Discovery Errors (20xx)
|
|
95
|
-
|
|
96
|
-
Errors that occur when discovering or accessing files:
|
|
97
|
-
|
|
98
|
-
```typescript
|
|
99
|
-
export enum IngestionErrorCode {
|
|
100
|
-
FILE_DISCOVERY_FAILED = 'FILE_DISCOVERY_FAILED', // Failed to discover files
|
|
101
|
-
FILE_ACCESS_DENIED = 'FILE_ACCESS_DENIED', // Permission denied
|
|
102
|
-
FILE_NOT_FOUND = 'FILE_NOT_FOUND', // File doesn't exist
|
|
103
|
-
INVALID_FILE_FORMAT = 'INVALID_FILE_FORMAT', // Unsupported file type
|
|
104
|
-
}
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
**When thrown:**
|
|
108
|
-
- Listing S3 bucket fails
|
|
109
|
-
- SFTP connection fails
|
|
110
|
-
- File permissions insufficient
|
|
111
|
-
- File path doesn't exist
|
|
112
|
-
|
|
113
|
-
**Retryable:** Usually Yes (network issues)
|
|
114
|
-
|
|
115
|
-
### Parsing Errors (21xx)
|
|
116
|
-
|
|
117
|
-
Errors during file content parsing:
|
|
118
|
-
|
|
119
|
-
```typescript
|
|
120
|
-
export enum IngestionErrorCode {
|
|
121
|
-
PARSE_ERROR = 'PARSE_ERROR', // Generic parsing error
|
|
122
|
-
INVALID_CSV_FORMAT = 'INVALID_CSV_FORMAT', // Malformed CSV
|
|
123
|
-
INVALID_PARQUET_FORMAT = 'INVALID_PARQUET_FORMAT', // Invalid Parquet file
|
|
124
|
-
ENCODING_ERROR = 'ENCODING_ERROR', // Character encoding issue
|
|
125
|
-
}
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
**When thrown:**
|
|
129
|
-
- XML is malformed (missing closing tag)
|
|
130
|
-
- JSON is invalid (syntax error)
|
|
131
|
-
- CSV has inconsistent columns
|
|
132
|
-
- Parquet file is corrupted
|
|
133
|
-
- Character encoding is not UTF-8
|
|
134
|
-
|
|
135
|
-
**Retryable:** No (source data issue)
|
|
136
|
-
|
|
137
|
-
### Transformation Errors (22xx)
|
|
138
|
-
|
|
139
|
-
Errors during field mapping and transformation:
|
|
140
|
-
|
|
141
|
-
```typescript
|
|
142
|
-
export enum IngestionErrorCode {
|
|
143
|
-
TRANSFORMATION_ERROR = 'TRANSFORMATION_ERROR', // Generic transformation error
|
|
144
|
-
FIELD_MAPPING_ERROR = 'FIELD_MAPPING_ERROR', // Field mapping failed
|
|
145
|
-
VALIDATION_ERROR = 'VALIDATION_ERROR', // Data validation failed
|
|
146
|
-
REQUIRED_FIELD_MISSING = 'REQUIRED_FIELD_MISSING', // Required field empty
|
|
147
|
-
}
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
**When thrown:**
|
|
151
|
-
- Required field is missing or empty
|
|
152
|
-
- Field type mismatch (expected number, got string)
|
|
153
|
-
- Array validation failed (minItems, maxItems)
|
|
154
|
-
- Custom resolver threw error
|
|
155
|
-
- Source path doesn't exist in data
|
|
156
|
-
|
|
157
|
-
**Retryable:** No (data or configuration issue)
|
|
158
|
-
|
|
159
|
-
### Submission Errors (23xx)
|
|
160
|
-
|
|
161
|
-
Errors when submitting to Fluent API:
|
|
162
|
-
|
|
163
|
-
```typescript
|
|
164
|
-
export enum IngestionErrorCode {
|
|
165
|
-
BATCH_SUBMISSION_ERROR = 'BATCH_SUBMISSION_ERROR', // Batch API error
|
|
166
|
-
JOB_CREATION_ERROR = 'JOB_CREATION_ERROR', // Job creation failed
|
|
167
|
-
API_ERROR = 'API_ERROR', // Fluent API error
|
|
168
|
-
NETWORK_ERROR = 'NETWORK_ERROR', // Network connectivity
|
|
169
|
-
}
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
**When thrown:**
|
|
173
|
-
- Batch API returns error response
|
|
174
|
-
- Job creation fails
|
|
175
|
-
- Network timeout
|
|
176
|
-
- API endpoint unreachable
|
|
177
|
-
|
|
178
|
-
**Retryable:** Usually Yes (transient failures)
|
|
179
|
-
|
|
180
|
-
> **Important:** `NETWORK_ERROR`, `TIMEOUT_ERROR`, and `RATE_LIMIT_ERROR` are error **codes** within `IngestionError`, not separate error classes. Check them using: `error instanceof IngestionError && error.code === IngestionErrorCode.NETWORK_ERROR`
|
|
181
|
-
|
|
182
|
-
### State Management Errors (24xx)
|
|
183
|
-
|
|
184
|
-
Errors related to state tracking and locking:
|
|
185
|
-
|
|
186
|
-
```typescript
|
|
187
|
-
export enum IngestionErrorCode {
|
|
188
|
-
LOCK_ACQUISITION_FAILED = 'LOCK_ACQUISITION_FAILED', // Failed to acquire lock
|
|
189
|
-
STATE_UPDATE_FAILED = 'STATE_UPDATE_FAILED', // State update failed
|
|
190
|
-
}
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
**When thrown:**
|
|
194
|
-
- Distributed lock acquisition fails
|
|
195
|
-
- KV store update fails
|
|
196
|
-
- Concurrent processing conflict
|
|
197
|
-
|
|
198
|
-
**Retryable:** Yes (transient issue)
|
|
199
|
-
|
|
200
|
-
### Configuration Errors (25xx)
|
|
201
|
-
|
|
202
|
-
Errors in SDK configuration:
|
|
203
|
-
|
|
204
|
-
```typescript
|
|
205
|
-
export enum IngestionErrorCode {
|
|
206
|
-
CONFIGURATION_ERROR = 'CONFIGURATION_ERROR', // Generic config error
|
|
207
|
-
MISSING_REQUIRED_CONFIG = 'MISSING_REQUIRED_CONFIG', // Required config missing
|
|
208
|
-
INVALID_CONFIGURATION = 'INVALID_CONFIGURATION', // Config value invalid
|
|
209
|
-
}
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
**When thrown:**
|
|
213
|
-
- Missing required environment variable
|
|
214
|
-
- Invalid configuration value
|
|
215
|
-
- Conflicting configuration options
|
|
216
|
-
|
|
217
|
-
**Retryable:** No (configuration issue)
|
|
218
|
-
|
|
219
|
-
### General Errors (26xx)
|
|
220
|
-
|
|
221
|
-
General operational errors:
|
|
222
|
-
|
|
223
|
-
```typescript
|
|
224
|
-
export enum IngestionErrorCode {
|
|
225
|
-
UNKNOWN_ERROR = 'UNKNOWN_ERROR', // Unexpected error
|
|
226
|
-
TIMEOUT_ERROR = 'TIMEOUT_ERROR', // Operation timeout
|
|
227
|
-
RATE_LIMIT_ERROR = 'RATE_LIMIT_ERROR', // API rate limit hit
|
|
228
|
-
}
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
**When thrown:**
|
|
232
|
-
- Unexpected exception caught
|
|
233
|
-
- Operation exceeds timeout
|
|
234
|
-
- API rate limit reached
|
|
235
|
-
|
|
236
|
-
**Retryable:** Depends (timeout/rate limit: yes, unknown: maybe)
|
|
237
|
-
|
|
238
|
-
## Specific Error Classes
|
|
239
|
-
|
|
240
|
-
### FileParsingError
|
|
241
|
-
|
|
242
|
-
Thrown when file parsing fails:
|
|
243
|
-
|
|
244
|
-
```typescript
|
|
245
|
-
class FileParsingError extends IngestionError {
|
|
246
|
-
readonly fileName?: string;
|
|
247
|
-
readonly lineNumber?: number;
|
|
248
|
-
}
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
**Example:**
|
|
252
|
-
|
|
253
|
-
```typescript
|
|
254
|
-
try {
|
|
255
|
-
const parsed = await parser.parse(xmlContent);
|
|
256
|
-
} catch (error) {
|
|
257
|
-
if (error instanceof FileParsingError) {
|
|
258
|
-
console.error(`Parsing failed in ${error.fileName} at line ${error.lineNumber}`);
|
|
259
|
-
console.error(`Reason: ${error.message}`);
|
|
260
|
-
// Don't retry - fix source file
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
**Common scenarios:**
|
|
266
|
-
- Invalid XML: `<order><customer>Missing closing tag`
|
|
267
|
-
- Invalid JSON: `{"key": value}` (unquoted value)
|
|
268
|
-
- Malformed CSV: Inconsistent column count
|
|
269
|
-
|
|
270
|
-
### PathResolutionError
|
|
271
|
-
|
|
272
|
-
Thrown when source path doesn't exist in data:
|
|
273
|
-
|
|
274
|
-
```typescript
|
|
275
|
-
class PathResolutionError extends Error {
|
|
276
|
-
readonly path: string;
|
|
277
|
-
readonly cause?: Error;
|
|
278
|
-
}
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
**Example:**
|
|
282
|
-
|
|
283
|
-
```typescript
|
|
284
|
-
// Mapping config
|
|
285
|
-
{
|
|
286
|
-
"ref": {
|
|
287
|
-
"source": "order.WRONG_PATH.customer-email"
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
// Result
|
|
292
|
-
try {
|
|
293
|
-
const payload = await mapper.map(parsed);
|
|
294
|
-
} catch (error) {
|
|
295
|
-
if (error instanceof PathResolutionError) {
|
|
296
|
-
console.error(`Path not found: ${error.path}`);
|
|
297
|
-
// Don't retry - fix mapping configuration
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
```
|
|
301
|
-
|
|
302
|
-
**Common scenarios:**
|
|
303
|
-
- Typo in source path
|
|
304
|
-
- Data structure changed
|
|
305
|
-
- Optional field accessed without null check
|
|
306
|
-
|
|
307
|
-
### MappingError
|
|
308
|
-
|
|
309
|
-
Thrown when field mapping fails:
|
|
310
|
-
|
|
311
|
-
```typescript
|
|
312
|
-
class MappingError extends Error {
|
|
313
|
-
readonly field?: string;
|
|
314
|
-
readonly sourcePath?: string;
|
|
315
|
-
}
|
|
316
|
-
```
|
|
317
|
-
|
|
318
|
-
**Example:**
|
|
319
|
-
|
|
320
|
-
```typescript
|
|
321
|
-
// Required field missing
|
|
322
|
-
try {
|
|
323
|
-
const payload = await mapper.map(parsed);
|
|
324
|
-
} catch (error) {
|
|
325
|
-
if (error instanceof MappingError) {
|
|
326
|
-
console.error(`Field: ${error.field}`);
|
|
327
|
-
console.error(`Source: ${error.sourcePath}`);
|
|
328
|
-
console.error(`Reason: ${error.message}`);
|
|
329
|
-
// Don't retry - fix data or mapping config
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
```
|
|
333
|
-
|
|
334
|
-
**Common scenarios:**
|
|
335
|
-
- Required field is missing or empty
|
|
336
|
-
- Array validation failed (minItems, maxItems)
|
|
337
|
-
- Type coercion failed
|
|
338
|
-
|
|
339
|
-
### ValidationError
|
|
340
|
-
|
|
341
|
-
Thrown when data validation rules fail:
|
|
342
|
-
|
|
343
|
-
```typescript
|
|
344
|
-
class ValidationError extends IngestionError {
|
|
345
|
-
readonly validationErrors: Array<{
|
|
346
|
-
field?: string;
|
|
347
|
-
value?: any;
|
|
348
|
-
rule?: string;
|
|
349
|
-
message: string;
|
|
350
|
-
}>;
|
|
351
|
-
}
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
**Example:**
|
|
355
|
-
|
|
356
|
-
```typescript
|
|
357
|
-
try {
|
|
358
|
-
const result = await validator.validate(data);
|
|
359
|
-
} catch (error) {
|
|
360
|
-
if (error instanceof ValidationError) {
|
|
361
|
-
error.validationErrors.forEach(err => {
|
|
362
|
-
console.error(`Field ${err.field} failed rule ${err.rule}: ${err.message}`);
|
|
363
|
-
});
|
|
364
|
-
// Don't retry - fix source data
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
**Common scenarios:**
|
|
370
|
-
- Email format invalid
|
|
371
|
-
- Date in wrong format
|
|
372
|
-
- Number out of range
|
|
373
|
-
- Custom validation rule failed
|
|
374
|
-
|
|
375
|
-
### ConfigurationError
|
|
376
|
-
|
|
377
|
-
Thrown when SDK configuration is invalid:
|
|
378
|
-
|
|
379
|
-
```typescript
|
|
380
|
-
class ConfigurationError extends IngestionError {
|
|
381
|
-
readonly configKey?: string;
|
|
382
|
-
}
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
**Example:**
|
|
386
|
-
|
|
387
|
-
```typescript
|
|
388
|
-
try {
|
|
389
|
-
const client = createClient({
|
|
390
|
-
baseUrl: undefined, // ❌ Required
|
|
391
|
-
});
|
|
392
|
-
} catch (error) {
|
|
393
|
-
if (error instanceof ConfigurationError) {
|
|
394
|
-
console.error(`Config error in ${error.configKey}: ${error.message}`);
|
|
395
|
-
// Don't retry - fix configuration
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
```
|
|
399
|
-
|
|
400
|
-
**Common scenarios:**
|
|
401
|
-
- Missing required environment variable
|
|
402
|
-
- Invalid URL format
|
|
403
|
-
- Conflicting configuration options
|
|
404
|
-
|
|
405
|
-
### BatchSubmissionError
|
|
406
|
-
|
|
407
|
-
Thrown when Batch API submission fails:
|
|
408
|
-
|
|
409
|
-
```typescript
|
|
410
|
-
class BatchSubmissionError extends IngestionError {
|
|
411
|
-
// Inherits all IngestionError properties
|
|
412
|
-
}
|
|
413
|
-
```
|
|
414
|
-
|
|
415
|
-
**Example:**
|
|
416
|
-
|
|
417
|
-
```typescript
|
|
418
|
-
try {
|
|
419
|
-
await client.sendBatch(jobId, { entities: data });
|
|
420
|
-
} catch (error) {
|
|
421
|
-
if (error instanceof BatchSubmissionError) {
|
|
422
|
-
console.error('Batch submission failed:', error.toJSON());
|
|
423
|
-
|
|
424
|
-
if (error.isRetryable()) {
|
|
425
|
-
// Retry with backoff
|
|
426
|
-
await retryWithBackoff(() => client.sendBatch(jobId, { entities: data }));
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
```
|
|
431
|
-
|
|
432
|
-
**Common scenarios:**
|
|
433
|
-
- Network timeout
|
|
434
|
-
- API temporarily unavailable
|
|
435
|
-
- Rate limit exceeded
|
|
436
|
-
|
|
437
|
-
### AggregateIngestionError
|
|
438
|
-
|
|
439
|
-
Thrown when multiple errors occur during batch processing:
|
|
440
|
-
|
|
441
|
-
```typescript
|
|
442
|
-
class AggregateIngestionError extends IngestionError {
|
|
443
|
-
readonly errors: IngestionError[];
|
|
444
|
-
}
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
**Example:**
|
|
448
|
-
|
|
449
|
-
```typescript
|
|
450
|
-
try {
|
|
451
|
-
await processMultipleFiles(files);
|
|
452
|
-
} catch (error) {
|
|
453
|
-
if (error instanceof AggregateIngestionError) {
|
|
454
|
-
console.error(`${error.errors.length} files failed:`);
|
|
455
|
-
error.errors.forEach(err => {
|
|
456
|
-
console.error(`- ${err.message} (${err.code})`);
|
|
457
|
-
});
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
```
|
|
461
|
-
|
|
462
|
-
**Common scenarios:**
|
|
463
|
-
- Batch file processing with some failures
|
|
464
|
-
- Multiple validation errors in different fields
|
|
465
|
-
- Parallel operations with multiple failures
|
|
466
|
-
|
|
467
|
-
## Services for Error Recovery
|
|
468
|
-
|
|
469
|
-
### PartialBatchRecovery
|
|
470
|
-
|
|
471
|
-
`PartialBatchRecovery` handles partial batch failures gracefully, allowing you to retry only failed records instead of the entire batch.
|
|
472
|
-
|
|
473
|
-
**Purpose:**
|
|
474
|
-
- Track success/failure per record
|
|
475
|
-
- Retry only failed records (not entire batch)
|
|
476
|
-
- Reduce processing overhead on retries
|
|
477
|
-
- Provide detailed error reporting per record
|
|
478
|
-
|
|
479
|
-
**Example:**
|
|
480
|
-
|
|
481
|
-
```typescript
|
|
482
|
-
import { PartialBatchRecovery, createClient, createConsoleLogger, toStructuredLogger } from '@fluentcommerce/fc-connect-sdk';
|
|
483
|
-
|
|
484
|
-
// Standalone
|
|
485
|
-
const logger = toStructuredLogger(createConsoleLogger(), { service: 'BatchRecovery' });
|
|
486
|
-
|
|
487
|
-
// Versori Platform
|
|
488
|
-
const { log: logger } = ctx;
|
|
489
|
-
|
|
490
|
-
const recovery = new PartialBatchRecovery(logger);
|
|
491
|
-
|
|
492
|
-
const result = await recovery.processBatchWithRecovery(
|
|
493
|
-
records,
|
|
494
|
-
async (batch) => {
|
|
495
|
-
// Your batch processing logic
|
|
496
|
-
const job = await client.createJob({ name: 'recovery', retailerId });
|
|
497
|
-
return await client.sendBatch(job.id, {
|
|
498
|
-
action: 'UPSERT',
|
|
499
|
-
entityType: 'INVENTORY',
|
|
500
|
-
entities: batch
|
|
501
|
-
});
|
|
502
|
-
},
|
|
503
|
-
{
|
|
504
|
-
maxRetries: 3, // Maximum retry attempts per failed record
|
|
505
|
-
retryOnlyFailed: true, // Only retry failed records (default: true)
|
|
506
|
-
batchSize: 100, // Batch size for retries
|
|
507
|
-
retryDelay: 1000 // Delay between retries (ms)
|
|
508
|
-
}
|
|
509
|
-
);
|
|
510
|
-
|
|
511
|
-
console.log(`Success: ${result.successCount}, Failed: ${result.failedCount}`);
|
|
512
|
-
console.log('Failed records:', result.failedRecords);
|
|
513
|
-
```
|
|
514
|
-
|
|
515
|
-
**Features:**
|
|
516
|
-
- ✅ Track which specific records failed
|
|
517
|
-
- ✅ Retry only failed records (not entire batch)
|
|
518
|
-
- ✅ Configurable retry attempts
|
|
519
|
-
- ✅ Detailed error reporting with record-level context
|
|
520
|
-
- ✅ Exponential backoff between retries
|
|
521
|
-
- ✅ Works with both Batch API and GraphQL mutations
|
|
522
|
-
|
|
523
|
-
**Use Cases:**
|
|
524
|
-
- Large batch imports where individual records may fail validation
|
|
525
|
-
- Network-related partial failures
|
|
526
|
-
- Rate limit handling with partial batch recovery
|
|
527
|
-
- Data quality issues affecting subset of records
|
|
528
|
-
|
|
529
|
-
**Return Value:**
|
|
530
|
-
```typescript
|
|
531
|
-
{
|
|
532
|
-
successCount: number; // Total successful records
|
|
533
|
-
failedCount: number; // Total failed records after all retries
|
|
534
|
-
failedRecords: Array<{ // Details of failed records
|
|
535
|
-
record: any; // The record that failed
|
|
536
|
-
error: Error; // The error that occurred
|
|
537
|
-
attemptCount: number; // How many times it was retried
|
|
538
|
-
}>;
|
|
539
|
-
}
|
|
540
|
-
```
|
|
541
|
-
|
|
542
|
-
### GraphQLExecutionError
|
|
543
|
-
|
|
544
|
-
Thrown when GraphQL mutation/query returns errors in response:
|
|
545
|
-
|
|
546
|
-
```typescript
|
|
547
|
-
class GraphQLExecutionError extends IngestionError {
|
|
548
|
-
readonly graphqlErrors: Array<{
|
|
549
|
-
message: string;
|
|
550
|
-
locations?: Array<{ line: number; column: number }>;
|
|
551
|
-
path?: Array<string | number>;
|
|
552
|
-
extensions?: Record<string, any>;
|
|
553
|
-
}>;
|
|
554
|
-
readonly query?: string;
|
|
555
|
-
readonly variables?: Record<string, any>;
|
|
556
|
-
|
|
557
|
-
getErrorMessages(): string[];
|
|
558
|
-
isValidationError(): boolean;
|
|
559
|
-
isAuthError(): boolean;
|
|
560
|
-
}
|
|
561
|
-
```
|
|
562
|
-
|
|
563
|
-
**Example:**
|
|
564
|
-
|
|
565
|
-
```typescript
|
|
566
|
-
try {
|
|
567
|
-
const result = await client.graphql({ query, variables });
|
|
568
|
-
} catch (error) {
|
|
569
|
-
if (error instanceof GraphQLExecutionError) {
|
|
570
|
-
console.error('GraphQL errors:', error.getErrorMessages());
|
|
571
|
-
|
|
572
|
-
if (error.isAuthError()) {
|
|
573
|
-
logger.error('Authentication failed');
|
|
574
|
-
} else if (error.isValidationError()) {
|
|
575
|
-
logger.error('GraphQL validation failed');
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
```
|
|
580
|
-
|
|
581
|
-
**Important:** Both `FluentClient` and `FluentVersoriClient` throw `GraphQLExecutionError` for GraphQL response errors. Previously, `FluentVersoriClient` returned errors in the response, but now it throws them for consistency and fail-fast behavior.
|
|
582
|
-
|
|
583
|
-
**Common scenarios:**
|
|
584
|
-
- GraphQL query/mutation validation errors
|
|
585
|
-
- Field permission errors
|
|
586
|
-
- Authentication/authorization failures
|
|
587
|
-
- GraphQL schema mismatches
|
|
588
|
-
|
|
589
|
-
### DataSourceError
|
|
590
|
-
|
|
591
|
-
Thrown when S3 or SFTP data source operations fail:
|
|
592
|
-
|
|
593
|
-
```typescript
|
|
594
|
-
class DataSourceError extends FluentError {
|
|
595
|
-
readonly source?: string;
|
|
596
|
-
readonly operation?: string;
|
|
597
|
-
readonly details?: Record<string, unknown>;
|
|
598
|
-
}
|
|
599
|
-
```
|
|
600
|
-
|
|
601
|
-
**Example:**
|
|
602
|
-
|
|
603
|
-
```typescript
|
|
604
|
-
try {
|
|
605
|
-
const content = await s3DataSource.downloadFile(key);
|
|
606
|
-
} catch (error) {
|
|
607
|
-
if (error instanceof DataSourceError) {
|
|
608
|
-
console.error('Data source operation failed:', {
|
|
609
|
-
source: error.source, // 'S3_CSV' or 'SFTP_CSV'
|
|
610
|
-
operation: error.operation, // 'downloadFile'
|
|
611
|
-
details: error.details // { bucket, key, statusCode }
|
|
612
|
-
});
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
```
|
|
616
|
-
|
|
617
|
-
**Common scenarios:**
|
|
618
|
-
- S3 download/upload failures
|
|
619
|
-
- SFTP connection errors
|
|
620
|
-
- File not found in bucket/server
|
|
621
|
-
- Permission denied errors
|
|
622
|
-
|
|
623
|
-
### ResolverError
|
|
624
|
-
|
|
625
|
-
**Purpose:** Thrown when a custom resolver fails during field transformation
|
|
626
|
-
|
|
627
|
-
**When it occurs:**
|
|
628
|
-
- Custom resolver throws an exception
|
|
629
|
-
- Resolver returns invalid type
|
|
630
|
-
- Helper function fails in resolver
|
|
631
|
-
|
|
632
|
-
**Example:**
|
|
633
|
-
|
|
634
|
-
```typescript
|
|
635
|
-
import { ResolverError, UniversalMapper } from '@fluentcommerce/fc-connect-sdk';
|
|
636
|
-
|
|
637
|
-
// Custom resolver that can throw ResolverError
|
|
638
|
-
const customResolvers = {
|
|
639
|
-
'custom.validateEmail': (value: string) => {
|
|
640
|
-
if (!value.includes('@')) {
|
|
641
|
-
throw new Error('Invalid email format');
|
|
642
|
-
}
|
|
643
|
-
return value.toLowerCase();
|
|
644
|
-
},
|
|
645
|
-
'custom.parseDate': (value: unknown) => {
|
|
646
|
-
if (typeof value !== 'string') {
|
|
647
|
-
throw new Error('Date must be a string');
|
|
648
|
-
}
|
|
649
|
-
const date = new Date(value);
|
|
650
|
-
if (isNaN(date.getTime())) {
|
|
651
|
-
throw new Error(`Invalid date: ${value}`);
|
|
652
|
-
}
|
|
653
|
-
return date.toISOString();
|
|
654
|
-
}
|
|
655
|
-
};
|
|
656
|
-
|
|
657
|
-
try {
|
|
658
|
-
const mapper = new UniversalMapper(config, { customResolvers });
|
|
659
|
-
const mapped = await mapper.map(data);
|
|
660
|
-
} catch (error) {
|
|
661
|
-
if (error instanceof ResolverError) {
|
|
662
|
-
// Structured error with complete context
|
|
663
|
-
console.error('Resolver failed:', {
|
|
664
|
-
resolver: error.resolverName, // 'custom.parseDate'
|
|
665
|
-
field: error.fieldName, // 'orderDate'
|
|
666
|
-
path: error.fieldPath, // ['order', 'orderDate']
|
|
667
|
-
input: error.inputValueSnippet, // 'invalid-date-string'
|
|
668
|
-
original: error.originalError.message, // Original error message
|
|
669
|
-
timestamp: error.timestamp
|
|
670
|
-
});
|
|
671
|
-
|
|
672
|
-
// Or use toJSON() for complete serialization
|
|
673
|
-
console.error('Complete error:', error.toJSON());
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
```
|
|
677
|
-
|
|
678
|
-
**Error Properties:**
|
|
679
|
-
- `resolverName`: Name of the resolver that failed (e.g., 'custom.parseDate')
|
|
680
|
-
- `fieldName`: Target field name being transformed
|
|
681
|
-
- `fieldPath`: Full path to the field in the data structure
|
|
682
|
-
- `inputValue`: The value that caused the failure
|
|
683
|
-
- `inputValueSnippet`: Truncated version of input for logging
|
|
684
|
-
- `originalError`: The underlying error thrown by the resolver
|
|
685
|
-
- `timestamp`: When the error occurred
|
|
686
|
-
|
|
687
|
-
**Common scenarios:**
|
|
688
|
-
- Custom date parsing failures
|
|
689
|
-
- Email validation errors
|
|
690
|
-
- Type conversion errors in resolvers
|
|
691
|
-
- Custom validation logic failures
|
|
692
|
-
- Transformation function exceptions
|
|
693
|
-
|
|
694
|
-
**Note:** ResolverError does NOT extend `IngestionError` - always a permanent error indicating resolver implementation or data issues.
|
|
695
|
-
|
|
696
|
-
## Using instanceof for Type Checking
|
|
697
|
-
|
|
698
|
-
The SDK exports all error classes for type checking:
|
|
699
|
-
|
|
700
|
-
```typescript
|
|
701
|
-
import {
|
|
702
|
-
// Ingestion errors
|
|
703
|
-
IngestionError,
|
|
704
|
-
FileParsingError,
|
|
705
|
-
ValidationError,
|
|
706
|
-
ConfigurationError,
|
|
707
|
-
GraphQLExecutionError,
|
|
708
|
-
|
|
709
|
-
// Mapping errors
|
|
710
|
-
MappingError,
|
|
711
|
-
ResolverError,
|
|
712
|
-
PathResolutionError,
|
|
713
|
-
|
|
714
|
-
// Data source errors
|
|
715
|
-
DataSourceError,
|
|
716
|
-
|
|
717
|
-
// Client errors (FluentClient and FluentVersoriClient)
|
|
718
|
-
FluentAPIError,
|
|
719
|
-
AuthenticationError
|
|
720
|
-
} from '@fluentcommerce/fc-connect-sdk';
|
|
721
|
-
|
|
722
|
-
async function handleOperation() {
|
|
723
|
-
try {
|
|
724
|
-
await processData();
|
|
725
|
-
} catch (error) {
|
|
726
|
-
// Check most specific errors first
|
|
727
|
-
if (error instanceof FileParsingError) {
|
|
728
|
-
// Handle parsing errors
|
|
729
|
-
logError('Parsing failed', error);
|
|
730
|
-
throw error; // Don't retry
|
|
731
|
-
|
|
732
|
-
} else if (error instanceof PathResolutionError) {
|
|
733
|
-
// Handle path errors
|
|
734
|
-
logError('Path resolution failed', error);
|
|
735
|
-
throw error; // Don't retry
|
|
736
|
-
|
|
737
|
-
} else if (error instanceof MappingError) {
|
|
738
|
-
// Handle mapping errors
|
|
739
|
-
logError('Mapping failed', error);
|
|
740
|
-
throw error; // Don't retry
|
|
741
|
-
|
|
742
|
-
} else if (error instanceof ValidationError) {
|
|
743
|
-
// Handle validation errors
|
|
744
|
-
logError('Validation failed', error);
|
|
745
|
-
throw error; // Don't retry
|
|
746
|
-
|
|
747
|
-
} else if (error instanceof ConfigurationError) {
|
|
748
|
-
// Handle config errors
|
|
749
|
-
logError('Configuration invalid', error);
|
|
750
|
-
throw error; // Don't retry
|
|
751
|
-
|
|
752
|
-
} else if (error instanceof FluentAPIError) {
|
|
753
|
-
// Handle API errors (400, 404, 500, etc.)
|
|
754
|
-
logError(`API Error: ${error.statusCode}`, error);
|
|
755
|
-
// Retry 5xx, fail 4xx
|
|
756
|
-
if (error.statusCode >= 500) {
|
|
757
|
-
return scheduleRetry();
|
|
758
|
-
}
|
|
759
|
-
throw error;
|
|
760
|
-
|
|
761
|
-
} else if (error instanceof AuthenticationError) {
|
|
762
|
-
// Handle Auth errors
|
|
763
|
-
logError('Authentication failed', error);
|
|
764
|
-
throw error; // Don't retry (already retried 3x)
|
|
765
|
-
|
|
766
|
-
} else if (error instanceof IngestionError) {
|
|
767
|
-
// Handle other ingestion errors
|
|
768
|
-
logError('Ingestion error', error);
|
|
769
|
-
|
|
770
|
-
// Check if retryable
|
|
771
|
-
if (error.isRetryable()) {
|
|
772
|
-
return scheduleRetry();
|
|
773
|
-
}
|
|
774
|
-
throw error;
|
|
775
|
-
|
|
776
|
-
} else {
|
|
777
|
-
// Unknown error
|
|
778
|
-
logError('Unknown error', error);
|
|
779
|
-
throw error;
|
|
780
|
-
}
|
|
781
|
-
}
|
|
782
|
-
}
|
|
783
|
-
```
|
|
784
|
-
|
|
785
|
-
## Error Object Structure
|
|
786
|
-
|
|
787
|
-
All SDK errors serialize to JSON with this structure:
|
|
788
|
-
|
|
789
|
-
```typescript
|
|
790
|
-
{
|
|
791
|
-
// Basic fields
|
|
792
|
-
name: "MappingError",
|
|
793
|
-
message: "Required field 'ref' is missing or empty",
|
|
794
|
-
|
|
795
|
-
// Error code (for programmatic handling)
|
|
796
|
-
code: "REQUIRED_FIELD_MISSING",
|
|
797
|
-
|
|
798
|
-
// Specific error details
|
|
799
|
-
field: "ref",
|
|
800
|
-
sourcePath: "order.ref",
|
|
801
|
-
|
|
802
|
-
// Additional context
|
|
803
|
-
context: {
|
|
804
|
-
recordIndex: 5,
|
|
805
|
-
fileName: "order-12345.xml",
|
|
806
|
-
mutation: "createOrder"
|
|
807
|
-
},
|
|
808
|
-
|
|
809
|
-
// Tracking
|
|
810
|
-
timestamp: "2025-01-10T12:34:56Z",
|
|
811
|
-
correlationId: "abc-123-def",
|
|
812
|
-
|
|
813
|
-
// Stack trace
|
|
814
|
-
stack: "Error: ...\n at ..."
|
|
815
|
-
}
|
|
816
|
-
```
|
|
817
|
-
|
|
818
|
-
## Key Takeaways
|
|
819
|
-
|
|
820
|
-
- 🎯 **Error hierarchy** - All ingestion errors extend `IngestionError`
|
|
821
|
-
- 🎯 **Error codes** - Use `IngestionErrorCode` enum for programmatic handling
|
|
822
|
-
- 🎯 **Specific classes** - Each error type has specific properties (fileName, field, etc.)
|
|
823
|
-
- 🎯 **Type checking** - Use `instanceof` to handle different error types
|
|
824
|
-
- 🎯 **JSON serialization** - All errors have `toJSON()` for logging
|
|
825
|
-
- 🎯 **Retry detection** - Use `isRetryable()` to determine retry strategy
|
|
826
|
-
|
|
827
|
-
## Practice Exercise
|
|
828
|
-
|
|
829
|
-
Match the error class to the scenario:
|
|
830
|
-
|
|
831
|
-
1. XML file has unclosed tag
|
|
832
|
-
2. Mapping config references non-existent field path
|
|
833
|
-
3. Required field is empty
|
|
834
|
-
4. Network timeout during API call
|
|
835
|
-
5. Missing environment variable
|
|
836
|
-
|
|
837
|
-
<details>
|
|
838
|
-
<summary>Click to see answers</summary>
|
|
839
|
-
|
|
840
|
-
1. `FileParsingError` - Parsing failed
|
|
841
|
-
2. `PathResolutionError` - Path doesn't exist
|
|
842
|
-
3. `MappingError` - Field mapping failed
|
|
843
|
-
4. `BatchSubmissionError` or `IngestionError` with `NETWORK_ERROR` - API error
|
|
844
|
-
5. `ConfigurationError` - Config invalid
|
|
845
|
-
|
|
846
|
-
</details>
|
|
847
|
-
|
|
848
|
-
## Next Steps
|
|
849
|
-
|
|
850
|
-
Continue to [Module 3: UTF-8 Handling →](./error-handling-03-utf8-handling.md) to learn about UTF-8 encoding and special character handling.
|
|
1
|
+
# Module 2: Error Types & Codes
|
|
2
|
+
|
|
3
|
+
**Level:** Beginner
|
|
4
|
+
**Estimated Time:** 20 minutes
|
|
5
|
+
|
|
6
|
+
## Overview
|
|
7
|
+
|
|
8
|
+
This module provides a complete reference to all error types and error codes in the SDK, including the error class hierarchy and when each error is thrown.
|
|
9
|
+
|
|
10
|
+
## Learning Objectives
|
|
11
|
+
|
|
12
|
+
By the end of this module, you will:
|
|
13
|
+
- ✅ Understand the error class hierarchy
|
|
14
|
+
- ✅ Know all available error codes and their meanings
|
|
15
|
+
- ✅ Recognize which error class is thrown for each scenario
|
|
16
|
+
- ✅ Use `instanceof` checks to handle specific error types
|
|
17
|
+
|
|
18
|
+
## Error Class Hierarchy
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
Error (JavaScript base class)
|
|
22
|
+
│
|
|
23
|
+
├── IngestionError (Ingestion base class)
|
|
24
|
+
│ ├── FileDiscoveryError
|
|
25
|
+
│ ├── FileParsingError
|
|
26
|
+
│ ├── TransformationError
|
|
27
|
+
│ ├── BatchSubmissionError
|
|
28
|
+
│ ├── ConfigurationError
|
|
29
|
+
│ ├── ValidationError
|
|
30
|
+
│ ├── GraphQLExecutionError
|
|
31
|
+
│ └── AggregateIngestionError
|
|
32
|
+
│
|
|
33
|
+
├── FluentError (Base SDK error class - used by services)
|
|
34
|
+
│ ├── FluentAPIError (HTTP errors from Fluent API)
|
|
35
|
+
│ ├── AuthenticationError (401 Unauthorized)
|
|
36
|
+
│ ├── FluentValidationError (Client-side validation)
|
|
37
|
+
│ ├── DataSourceError (S3/SFTP data source errors)
|
|
38
|
+
│ └── WebhookValidationError (Webhook signature validation errors)
|
|
39
|
+
│
|
|
40
|
+
├── MappingError (Field mapping errors - standalone)
|
|
41
|
+
│
|
|
42
|
+
├── ResolverError (Resolver transformation errors - standalone)
|
|
43
|
+
│
|
|
44
|
+
└── PathResolutionError (Path resolution errors - standalone)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Key Points:**
|
|
48
|
+
- `IngestionError` is the base class for all ingestion-related errors
|
|
49
|
+
- `PathResolutionError`, `MappingError`, and `ResolverError` do NOT extend `IngestionError` - they are standalone error classes
|
|
50
|
+
- `FluentError` is used by SDK services (S3, SFTP, webhooks) - separate from ingestion errors
|
|
51
|
+
|
|
52
|
+
### Base Classes
|
|
53
|
+
|
|
54
|
+
#### IngestionError (SDK Base)
|
|
55
|
+
|
|
56
|
+
The base class for all ingestion-related errors:
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
class IngestionError extends Error {
|
|
60
|
+
readonly code: IngestionErrorCode;
|
|
61
|
+
readonly context?: Record<string, any>;
|
|
62
|
+
readonly timestamp: Date;
|
|
63
|
+
readonly correlationId?: string;
|
|
64
|
+
|
|
65
|
+
toJSON(): Record<string, any>;
|
|
66
|
+
isRetryable(): boolean;
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Key features:**
|
|
71
|
+
- `code`: Machine-readable error code for programmatic handling
|
|
72
|
+
- `context`: Additional error context (file name, record index, etc.)
|
|
73
|
+
- `timestamp`: When the error occurred
|
|
74
|
+
- `correlationId`: For tracking errors across distributed systems
|
|
75
|
+
- `toJSON()`: Serialize error for logging/monitoring
|
|
76
|
+
- `isRetryable()`: Check if error should be retried
|
|
77
|
+
|
|
78
|
+
**Usage:**
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
try {
|
|
82
|
+
await processFile(fileName);
|
|
83
|
+
} catch (error) {
|
|
84
|
+
if (error instanceof IngestionError) {
|
|
85
|
+
console.log('Error code:', error.code);
|
|
86
|
+
console.log('Error JSON:', error.toJSON());
|
|
87
|
+
console.log('Can retry?', error.isRetryable());
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Error Codes Reference
|
|
93
|
+
|
|
94
|
+
### File Discovery Errors (20xx)
|
|
95
|
+
|
|
96
|
+
Errors that occur when discovering or accessing files:
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
export enum IngestionErrorCode {
|
|
100
|
+
FILE_DISCOVERY_FAILED = 'FILE_DISCOVERY_FAILED', // Failed to discover files
|
|
101
|
+
FILE_ACCESS_DENIED = 'FILE_ACCESS_DENIED', // Permission denied
|
|
102
|
+
FILE_NOT_FOUND = 'FILE_NOT_FOUND', // File doesn't exist
|
|
103
|
+
INVALID_FILE_FORMAT = 'INVALID_FILE_FORMAT', // Unsupported file type
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**When thrown:**
|
|
108
|
+
- Listing S3 bucket fails
|
|
109
|
+
- SFTP connection fails
|
|
110
|
+
- File permissions insufficient
|
|
111
|
+
- File path doesn't exist
|
|
112
|
+
|
|
113
|
+
**Retryable:** Usually Yes (network issues)
|
|
114
|
+
|
|
115
|
+
### Parsing Errors (21xx)
|
|
116
|
+
|
|
117
|
+
Errors during file content parsing:
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
export enum IngestionErrorCode {
|
|
121
|
+
PARSE_ERROR = 'PARSE_ERROR', // Generic parsing error
|
|
122
|
+
INVALID_CSV_FORMAT = 'INVALID_CSV_FORMAT', // Malformed CSV
|
|
123
|
+
INVALID_PARQUET_FORMAT = 'INVALID_PARQUET_FORMAT', // Invalid Parquet file
|
|
124
|
+
ENCODING_ERROR = 'ENCODING_ERROR', // Character encoding issue
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**When thrown:**
|
|
129
|
+
- XML is malformed (missing closing tag)
|
|
130
|
+
- JSON is invalid (syntax error)
|
|
131
|
+
- CSV has inconsistent columns
|
|
132
|
+
- Parquet file is corrupted
|
|
133
|
+
- Character encoding is not UTF-8
|
|
134
|
+
|
|
135
|
+
**Retryable:** No (source data issue)
|
|
136
|
+
|
|
137
|
+
### Transformation Errors (22xx)
|
|
138
|
+
|
|
139
|
+
Errors during field mapping and transformation:
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
export enum IngestionErrorCode {
|
|
143
|
+
TRANSFORMATION_ERROR = 'TRANSFORMATION_ERROR', // Generic transformation error
|
|
144
|
+
FIELD_MAPPING_ERROR = 'FIELD_MAPPING_ERROR', // Field mapping failed
|
|
145
|
+
VALIDATION_ERROR = 'VALIDATION_ERROR', // Data validation failed
|
|
146
|
+
REQUIRED_FIELD_MISSING = 'REQUIRED_FIELD_MISSING', // Required field empty
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**When thrown:**
|
|
151
|
+
- Required field is missing or empty
|
|
152
|
+
- Field type mismatch (expected number, got string)
|
|
153
|
+
- Array validation failed (minItems, maxItems)
|
|
154
|
+
- Custom resolver threw error
|
|
155
|
+
- Source path doesn't exist in data
|
|
156
|
+
|
|
157
|
+
**Retryable:** No (data or configuration issue)
|
|
158
|
+
|
|
159
|
+
### Submission Errors (23xx)
|
|
160
|
+
|
|
161
|
+
Errors when submitting to Fluent API:
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
export enum IngestionErrorCode {
|
|
165
|
+
BATCH_SUBMISSION_ERROR = 'BATCH_SUBMISSION_ERROR', // Batch API error
|
|
166
|
+
JOB_CREATION_ERROR = 'JOB_CREATION_ERROR', // Job creation failed
|
|
167
|
+
API_ERROR = 'API_ERROR', // Fluent API error
|
|
168
|
+
NETWORK_ERROR = 'NETWORK_ERROR', // Network connectivity
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
**When thrown:**
|
|
173
|
+
- Batch API returns error response
|
|
174
|
+
- Job creation fails
|
|
175
|
+
- Network timeout
|
|
176
|
+
- API endpoint unreachable
|
|
177
|
+
|
|
178
|
+
**Retryable:** Usually Yes (transient failures)
|
|
179
|
+
|
|
180
|
+
> **Important:** `NETWORK_ERROR`, `TIMEOUT_ERROR`, and `RATE_LIMIT_ERROR` are error **codes** within `IngestionError`, not separate error classes. Check them using: `error instanceof IngestionError && error.code === IngestionErrorCode.NETWORK_ERROR`
|
|
181
|
+
|
|
182
|
+
### State Management Errors (24xx)
|
|
183
|
+
|
|
184
|
+
Errors related to state tracking and locking:
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
export enum IngestionErrorCode {
|
|
188
|
+
LOCK_ACQUISITION_FAILED = 'LOCK_ACQUISITION_FAILED', // Failed to acquire lock
|
|
189
|
+
STATE_UPDATE_FAILED = 'STATE_UPDATE_FAILED', // State update failed
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**When thrown:**
|
|
194
|
+
- Distributed lock acquisition fails
|
|
195
|
+
- KV store update fails
|
|
196
|
+
- Concurrent processing conflict
|
|
197
|
+
|
|
198
|
+
**Retryable:** Yes (transient issue)
|
|
199
|
+
|
|
200
|
+
### Configuration Errors (25xx)
|
|
201
|
+
|
|
202
|
+
Errors in SDK configuration:
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
export enum IngestionErrorCode {
|
|
206
|
+
CONFIGURATION_ERROR = 'CONFIGURATION_ERROR', // Generic config error
|
|
207
|
+
MISSING_REQUIRED_CONFIG = 'MISSING_REQUIRED_CONFIG', // Required config missing
|
|
208
|
+
INVALID_CONFIGURATION = 'INVALID_CONFIGURATION', // Config value invalid
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
**When thrown:**
|
|
213
|
+
- Missing required environment variable
|
|
214
|
+
- Invalid configuration value
|
|
215
|
+
- Conflicting configuration options
|
|
216
|
+
|
|
217
|
+
**Retryable:** No (configuration issue)
|
|
218
|
+
|
|
219
|
+
### General Errors (26xx)
|
|
220
|
+
|
|
221
|
+
General operational errors:
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
export enum IngestionErrorCode {
|
|
225
|
+
UNKNOWN_ERROR = 'UNKNOWN_ERROR', // Unexpected error
|
|
226
|
+
TIMEOUT_ERROR = 'TIMEOUT_ERROR', // Operation timeout
|
|
227
|
+
RATE_LIMIT_ERROR = 'RATE_LIMIT_ERROR', // API rate limit hit
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**When thrown:**
|
|
232
|
+
- Unexpected exception caught
|
|
233
|
+
- Operation exceeds timeout
|
|
234
|
+
- API rate limit reached
|
|
235
|
+
|
|
236
|
+
**Retryable:** Depends (timeout/rate limit: yes, unknown: maybe)
|
|
237
|
+
|
|
238
|
+
## Specific Error Classes
|
|
239
|
+
|
|
240
|
+
### FileParsingError
|
|
241
|
+
|
|
242
|
+
Thrown when file parsing fails:
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
class FileParsingError extends IngestionError {
|
|
246
|
+
readonly fileName?: string;
|
|
247
|
+
readonly lineNumber?: number;
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
**Example:**
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
try {
|
|
255
|
+
const parsed = await parser.parse(xmlContent);
|
|
256
|
+
} catch (error) {
|
|
257
|
+
if (error instanceof FileParsingError) {
|
|
258
|
+
console.error(`Parsing failed in ${error.fileName} at line ${error.lineNumber}`);
|
|
259
|
+
console.error(`Reason: ${error.message}`);
|
|
260
|
+
// Don't retry - fix source file
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
**Common scenarios:**
|
|
266
|
+
- Invalid XML: `<order><customer>Missing closing tag`
|
|
267
|
+
- Invalid JSON: `{"key": value}` (unquoted value)
|
|
268
|
+
- Malformed CSV: Inconsistent column count
|
|
269
|
+
|
|
270
|
+
### PathResolutionError
|
|
271
|
+
|
|
272
|
+
Thrown when source path doesn't exist in data:
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
class PathResolutionError extends Error {
|
|
276
|
+
readonly path: string;
|
|
277
|
+
readonly cause?: Error;
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
**Example:**
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
// Mapping config
|
|
285
|
+
{
|
|
286
|
+
"ref": {
|
|
287
|
+
"source": "order.WRONG_PATH.customer-email"
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Result
|
|
292
|
+
try {
|
|
293
|
+
const payload = await mapper.map(parsed);
|
|
294
|
+
} catch (error) {
|
|
295
|
+
if (error instanceof PathResolutionError) {
|
|
296
|
+
console.error(`Path not found: ${error.path}`);
|
|
297
|
+
// Don't retry - fix mapping configuration
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
**Common scenarios:**
|
|
303
|
+
- Typo in source path
|
|
304
|
+
- Data structure changed
|
|
305
|
+
- Optional field accessed without null check
|
|
306
|
+
|
|
307
|
+
### MappingError
|
|
308
|
+
|
|
309
|
+
Thrown when field mapping fails:
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
class MappingError extends Error {
|
|
313
|
+
readonly field?: string;
|
|
314
|
+
readonly sourcePath?: string;
|
|
315
|
+
}
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
**Example:**
|
|
319
|
+
|
|
320
|
+
```typescript
|
|
321
|
+
// Required field missing
|
|
322
|
+
try {
|
|
323
|
+
const payload = await mapper.map(parsed);
|
|
324
|
+
} catch (error) {
|
|
325
|
+
if (error instanceof MappingError) {
|
|
326
|
+
console.error(`Field: ${error.field}`);
|
|
327
|
+
console.error(`Source: ${error.sourcePath}`);
|
|
328
|
+
console.error(`Reason: ${error.message}`);
|
|
329
|
+
// Don't retry - fix data or mapping config
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
**Common scenarios:**
|
|
335
|
+
- Required field is missing or empty
|
|
336
|
+
- Array validation failed (minItems, maxItems)
|
|
337
|
+
- Type coercion failed
|
|
338
|
+
|
|
339
|
+
### ValidationError
|
|
340
|
+
|
|
341
|
+
Thrown when data validation rules fail:
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
class ValidationError extends IngestionError {
|
|
345
|
+
readonly validationErrors: Array<{
|
|
346
|
+
field?: string;
|
|
347
|
+
value?: any;
|
|
348
|
+
rule?: string;
|
|
349
|
+
message: string;
|
|
350
|
+
}>;
|
|
351
|
+
}
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
**Example:**
|
|
355
|
+
|
|
356
|
+
```typescript
|
|
357
|
+
try {
|
|
358
|
+
const result = await validator.validate(data);
|
|
359
|
+
} catch (error) {
|
|
360
|
+
if (error instanceof ValidationError) {
|
|
361
|
+
error.validationErrors.forEach(err => {
|
|
362
|
+
console.error(`Field ${err.field} failed rule ${err.rule}: ${err.message}`);
|
|
363
|
+
});
|
|
364
|
+
// Don't retry - fix source data
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
**Common scenarios:**
|
|
370
|
+
- Email format invalid
|
|
371
|
+
- Date in wrong format
|
|
372
|
+
- Number out of range
|
|
373
|
+
- Custom validation rule failed
|
|
374
|
+
|
|
375
|
+
### ConfigurationError
|
|
376
|
+
|
|
377
|
+
Thrown when SDK configuration is invalid:
|
|
378
|
+
|
|
379
|
+
```typescript
|
|
380
|
+
class ConfigurationError extends IngestionError {
|
|
381
|
+
readonly configKey?: string;
|
|
382
|
+
}
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
**Example:**
|
|
386
|
+
|
|
387
|
+
```typescript
|
|
388
|
+
try {
|
|
389
|
+
const client = createClient({
|
|
390
|
+
baseUrl: undefined, // ❌ Required
|
|
391
|
+
});
|
|
392
|
+
} catch (error) {
|
|
393
|
+
if (error instanceof ConfigurationError) {
|
|
394
|
+
console.error(`Config error in ${error.configKey}: ${error.message}`);
|
|
395
|
+
// Don't retry - fix configuration
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
**Common scenarios:**
|
|
401
|
+
- Missing required environment variable
|
|
402
|
+
- Invalid URL format
|
|
403
|
+
- Conflicting configuration options
|
|
404
|
+
|
|
405
|
+
### BatchSubmissionError
|
|
406
|
+
|
|
407
|
+
Thrown when Batch API submission fails:
|
|
408
|
+
|
|
409
|
+
```typescript
|
|
410
|
+
class BatchSubmissionError extends IngestionError {
|
|
411
|
+
// Inherits all IngestionError properties
|
|
412
|
+
}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
**Example:**
|
|
416
|
+
|
|
417
|
+
```typescript
|
|
418
|
+
try {
|
|
419
|
+
await client.sendBatch(jobId, { entities: data });
|
|
420
|
+
} catch (error) {
|
|
421
|
+
if (error instanceof BatchSubmissionError) {
|
|
422
|
+
console.error('Batch submission failed:', error.toJSON());
|
|
423
|
+
|
|
424
|
+
if (error.isRetryable()) {
|
|
425
|
+
// Retry with backoff
|
|
426
|
+
await retryWithBackoff(() => client.sendBatch(jobId, { entities: data }));
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
**Common scenarios:**
|
|
433
|
+
- Network timeout
|
|
434
|
+
- API temporarily unavailable
|
|
435
|
+
- Rate limit exceeded
|
|
436
|
+
|
|
437
|
+
### AggregateIngestionError
|
|
438
|
+
|
|
439
|
+
Thrown when multiple errors occur during batch processing:
|
|
440
|
+
|
|
441
|
+
```typescript
|
|
442
|
+
class AggregateIngestionError extends IngestionError {
|
|
443
|
+
readonly errors: IngestionError[];
|
|
444
|
+
}
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
**Example:**
|
|
448
|
+
|
|
449
|
+
```typescript
|
|
450
|
+
try {
|
|
451
|
+
await processMultipleFiles(files);
|
|
452
|
+
} catch (error) {
|
|
453
|
+
if (error instanceof AggregateIngestionError) {
|
|
454
|
+
console.error(`${error.errors.length} files failed:`);
|
|
455
|
+
error.errors.forEach(err => {
|
|
456
|
+
console.error(`- ${err.message} (${err.code})`);
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
**Common scenarios:**
|
|
463
|
+
- Batch file processing with some failures
|
|
464
|
+
- Multiple validation errors in different fields
|
|
465
|
+
- Parallel operations with multiple failures
|
|
466
|
+
|
|
467
|
+
## Services for Error Recovery
|
|
468
|
+
|
|
469
|
+
### PartialBatchRecovery
|
|
470
|
+
|
|
471
|
+
`PartialBatchRecovery` handles partial batch failures gracefully, allowing you to retry only failed records instead of the entire batch.
|
|
472
|
+
|
|
473
|
+
**Purpose:**
|
|
474
|
+
- Track success/failure per record
|
|
475
|
+
- Retry only failed records (not entire batch)
|
|
476
|
+
- Reduce processing overhead on retries
|
|
477
|
+
- Provide detailed error reporting per record
|
|
478
|
+
|
|
479
|
+
**Example:**
|
|
480
|
+
|
|
481
|
+
```typescript
|
|
482
|
+
import { PartialBatchRecovery, createClient, createConsoleLogger, toStructuredLogger } from '@fluentcommerce/fc-connect-sdk';
|
|
483
|
+
|
|
484
|
+
// Standalone
|
|
485
|
+
const logger = toStructuredLogger(createConsoleLogger(), { service: 'BatchRecovery' });
|
|
486
|
+
|
|
487
|
+
// Versori Platform
|
|
488
|
+
const { log: logger } = ctx;
|
|
489
|
+
|
|
490
|
+
const recovery = new PartialBatchRecovery(logger);
|
|
491
|
+
|
|
492
|
+
const result = await recovery.processBatchWithRecovery(
|
|
493
|
+
records,
|
|
494
|
+
async (batch) => {
|
|
495
|
+
// Your batch processing logic
|
|
496
|
+
const job = await client.createJob({ name: 'recovery', retailerId });
|
|
497
|
+
return await client.sendBatch(job.id, {
|
|
498
|
+
action: 'UPSERT',
|
|
499
|
+
entityType: 'INVENTORY',
|
|
500
|
+
entities: batch
|
|
501
|
+
});
|
|
502
|
+
},
|
|
503
|
+
{
|
|
504
|
+
maxRetries: 3, // Maximum retry attempts per failed record
|
|
505
|
+
retryOnlyFailed: true, // Only retry failed records (default: true)
|
|
506
|
+
batchSize: 100, // Batch size for retries
|
|
507
|
+
retryDelay: 1000 // Delay between retries (ms)
|
|
508
|
+
}
|
|
509
|
+
);
|
|
510
|
+
|
|
511
|
+
console.log(`Success: ${result.successCount}, Failed: ${result.failedCount}`);
|
|
512
|
+
console.log('Failed records:', result.failedRecords);
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
**Features:**
|
|
516
|
+
- ✅ Track which specific records failed
|
|
517
|
+
- ✅ Retry only failed records (not entire batch)
|
|
518
|
+
- ✅ Configurable retry attempts
|
|
519
|
+
- ✅ Detailed error reporting with record-level context
|
|
520
|
+
- ✅ Exponential backoff between retries
|
|
521
|
+
- ✅ Works with both Batch API and GraphQL mutations
|
|
522
|
+
|
|
523
|
+
**Use Cases:**
|
|
524
|
+
- Large batch imports where individual records may fail validation
|
|
525
|
+
- Network-related partial failures
|
|
526
|
+
- Rate limit handling with partial batch recovery
|
|
527
|
+
- Data quality issues affecting subset of records
|
|
528
|
+
|
|
529
|
+
**Return Value:**
|
|
530
|
+
```typescript
|
|
531
|
+
{
|
|
532
|
+
successCount: number; // Total successful records
|
|
533
|
+
failedCount: number; // Total failed records after all retries
|
|
534
|
+
failedRecords: Array<{ // Details of failed records
|
|
535
|
+
record: any; // The record that failed
|
|
536
|
+
error: Error; // The error that occurred
|
|
537
|
+
attemptCount: number; // How many times it was retried
|
|
538
|
+
}>;
|
|
539
|
+
}
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
### GraphQLExecutionError
|
|
543
|
+
|
|
544
|
+
Thrown when GraphQL mutation/query returns errors in response:
|
|
545
|
+
|
|
546
|
+
```typescript
|
|
547
|
+
class GraphQLExecutionError extends IngestionError {
|
|
548
|
+
readonly graphqlErrors: Array<{
|
|
549
|
+
message: string;
|
|
550
|
+
locations?: Array<{ line: number; column: number }>;
|
|
551
|
+
path?: Array<string | number>;
|
|
552
|
+
extensions?: Record<string, any>;
|
|
553
|
+
}>;
|
|
554
|
+
readonly query?: string;
|
|
555
|
+
readonly variables?: Record<string, any>;
|
|
556
|
+
|
|
557
|
+
getErrorMessages(): string[];
|
|
558
|
+
isValidationError(): boolean;
|
|
559
|
+
isAuthError(): boolean;
|
|
560
|
+
}
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
**Example:**
|
|
564
|
+
|
|
565
|
+
```typescript
|
|
566
|
+
try {
|
|
567
|
+
const result = await client.graphql({ query, variables });
|
|
568
|
+
} catch (error) {
|
|
569
|
+
if (error instanceof GraphQLExecutionError) {
|
|
570
|
+
console.error('GraphQL errors:', error.getErrorMessages());
|
|
571
|
+
|
|
572
|
+
if (error.isAuthError()) {
|
|
573
|
+
logger.error('Authentication failed');
|
|
574
|
+
} else if (error.isValidationError()) {
|
|
575
|
+
logger.error('GraphQL validation failed');
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
**Important:** Both `FluentClient` and `FluentVersoriClient` throw `GraphQLExecutionError` for GraphQL response errors. Previously, `FluentVersoriClient` returned errors in the response, but now it throws them for consistency and fail-fast behavior.
|
|
582
|
+
|
|
583
|
+
**Common scenarios:**
|
|
584
|
+
- GraphQL query/mutation validation errors
|
|
585
|
+
- Field permission errors
|
|
586
|
+
- Authentication/authorization failures
|
|
587
|
+
- GraphQL schema mismatches
|
|
588
|
+
|
|
589
|
+
### DataSourceError
|
|
590
|
+
|
|
591
|
+
Thrown when S3 or SFTP data source operations fail:
|
|
592
|
+
|
|
593
|
+
```typescript
|
|
594
|
+
class DataSourceError extends FluentError {
|
|
595
|
+
readonly source?: string;
|
|
596
|
+
readonly operation?: string;
|
|
597
|
+
readonly details?: Record<string, unknown>;
|
|
598
|
+
}
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
**Example:**
|
|
602
|
+
|
|
603
|
+
```typescript
|
|
604
|
+
try {
|
|
605
|
+
const content = await s3DataSource.downloadFile(key);
|
|
606
|
+
} catch (error) {
|
|
607
|
+
if (error instanceof DataSourceError) {
|
|
608
|
+
console.error('Data source operation failed:', {
|
|
609
|
+
source: error.source, // 'S3_CSV' or 'SFTP_CSV'
|
|
610
|
+
operation: error.operation, // 'downloadFile'
|
|
611
|
+
details: error.details // { bucket, key, statusCode }
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
**Common scenarios:**
|
|
618
|
+
- S3 download/upload failures
|
|
619
|
+
- SFTP connection errors
|
|
620
|
+
- File not found in bucket/server
|
|
621
|
+
- Permission denied errors
|
|
622
|
+
|
|
623
|
+
### ResolverError
|
|
624
|
+
|
|
625
|
+
**Purpose:** Thrown when a custom resolver fails during field transformation
|
|
626
|
+
|
|
627
|
+
**When it occurs:**
|
|
628
|
+
- Custom resolver throws an exception
|
|
629
|
+
- Resolver returns invalid type
|
|
630
|
+
- Helper function fails in resolver
|
|
631
|
+
|
|
632
|
+
**Example:**
|
|
633
|
+
|
|
634
|
+
```typescript
|
|
635
|
+
import { ResolverError, UniversalMapper } from '@fluentcommerce/fc-connect-sdk';
|
|
636
|
+
|
|
637
|
+
// Custom resolver that can throw ResolverError
|
|
638
|
+
const customResolvers = {
|
|
639
|
+
'custom.validateEmail': (value: string) => {
|
|
640
|
+
if (!value.includes('@')) {
|
|
641
|
+
throw new Error('Invalid email format');
|
|
642
|
+
}
|
|
643
|
+
return value.toLowerCase();
|
|
644
|
+
},
|
|
645
|
+
'custom.parseDate': (value: unknown) => {
|
|
646
|
+
if (typeof value !== 'string') {
|
|
647
|
+
throw new Error('Date must be a string');
|
|
648
|
+
}
|
|
649
|
+
const date = new Date(value);
|
|
650
|
+
if (isNaN(date.getTime())) {
|
|
651
|
+
throw new Error(`Invalid date: ${value}`);
|
|
652
|
+
}
|
|
653
|
+
return date.toISOString();
|
|
654
|
+
}
|
|
655
|
+
};
|
|
656
|
+
|
|
657
|
+
try {
|
|
658
|
+
const mapper = new UniversalMapper(config, { customResolvers });
|
|
659
|
+
const mapped = await mapper.map(data);
|
|
660
|
+
} catch (error) {
|
|
661
|
+
if (error instanceof ResolverError) {
|
|
662
|
+
// Structured error with complete context
|
|
663
|
+
console.error('Resolver failed:', {
|
|
664
|
+
resolver: error.resolverName, // 'custom.parseDate'
|
|
665
|
+
field: error.fieldName, // 'orderDate'
|
|
666
|
+
path: error.fieldPath, // ['order', 'orderDate']
|
|
667
|
+
input: error.inputValueSnippet, // 'invalid-date-string'
|
|
668
|
+
original: error.originalError.message, // Original error message
|
|
669
|
+
timestamp: error.timestamp
|
|
670
|
+
});
|
|
671
|
+
|
|
672
|
+
// Or use toJSON() for complete serialization
|
|
673
|
+
console.error('Complete error:', error.toJSON());
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
**Error Properties:**
|
|
679
|
+
- `resolverName`: Name of the resolver that failed (e.g., 'custom.parseDate')
|
|
680
|
+
- `fieldName`: Target field name being transformed
|
|
681
|
+
- `fieldPath`: Full path to the field in the data structure
|
|
682
|
+
- `inputValue`: The value that caused the failure
|
|
683
|
+
- `inputValueSnippet`: Truncated version of input for logging
|
|
684
|
+
- `originalError`: The underlying error thrown by the resolver
|
|
685
|
+
- `timestamp`: When the error occurred
|
|
686
|
+
|
|
687
|
+
**Common scenarios:**
|
|
688
|
+
- Custom date parsing failures
|
|
689
|
+
- Email validation errors
|
|
690
|
+
- Type conversion errors in resolvers
|
|
691
|
+
- Custom validation logic failures
|
|
692
|
+
- Transformation function exceptions
|
|
693
|
+
|
|
694
|
+
**Note:** ResolverError does NOT extend `IngestionError` - always a permanent error indicating resolver implementation or data issues.
|
|
695
|
+
|
|
696
|
+
## Using instanceof for Type Checking
|
|
697
|
+
|
|
698
|
+
The SDK exports all error classes for type checking:
|
|
699
|
+
|
|
700
|
+
```typescript
|
|
701
|
+
import {
|
|
702
|
+
// Ingestion errors
|
|
703
|
+
IngestionError,
|
|
704
|
+
FileParsingError,
|
|
705
|
+
ValidationError,
|
|
706
|
+
ConfigurationError,
|
|
707
|
+
GraphQLExecutionError,
|
|
708
|
+
|
|
709
|
+
// Mapping errors
|
|
710
|
+
MappingError,
|
|
711
|
+
ResolverError,
|
|
712
|
+
PathResolutionError,
|
|
713
|
+
|
|
714
|
+
// Data source errors
|
|
715
|
+
DataSourceError,
|
|
716
|
+
|
|
717
|
+
// Client errors (FluentClient and FluentVersoriClient)
|
|
718
|
+
FluentAPIError,
|
|
719
|
+
AuthenticationError
|
|
720
|
+
} from '@fluentcommerce/fc-connect-sdk';
|
|
721
|
+
|
|
722
|
+
async function handleOperation() {
|
|
723
|
+
try {
|
|
724
|
+
await processData();
|
|
725
|
+
} catch (error) {
|
|
726
|
+
// Check most specific errors first
|
|
727
|
+
if (error instanceof FileParsingError) {
|
|
728
|
+
// Handle parsing errors
|
|
729
|
+
logError('Parsing failed', error);
|
|
730
|
+
throw error; // Don't retry
|
|
731
|
+
|
|
732
|
+
} else if (error instanceof PathResolutionError) {
|
|
733
|
+
// Handle path errors
|
|
734
|
+
logError('Path resolution failed', error);
|
|
735
|
+
throw error; // Don't retry
|
|
736
|
+
|
|
737
|
+
} else if (error instanceof MappingError) {
|
|
738
|
+
// Handle mapping errors
|
|
739
|
+
logError('Mapping failed', error);
|
|
740
|
+
throw error; // Don't retry
|
|
741
|
+
|
|
742
|
+
} else if (error instanceof ValidationError) {
|
|
743
|
+
// Handle validation errors
|
|
744
|
+
logError('Validation failed', error);
|
|
745
|
+
throw error; // Don't retry
|
|
746
|
+
|
|
747
|
+
} else if (error instanceof ConfigurationError) {
|
|
748
|
+
// Handle config errors
|
|
749
|
+
logError('Configuration invalid', error);
|
|
750
|
+
throw error; // Don't retry
|
|
751
|
+
|
|
752
|
+
} else if (error instanceof FluentAPIError) {
|
|
753
|
+
// Handle API errors (400, 404, 500, etc.)
|
|
754
|
+
logError(`API Error: ${error.statusCode}`, error);
|
|
755
|
+
// Retry 5xx, fail 4xx
|
|
756
|
+
if (error.statusCode >= 500) {
|
|
757
|
+
return scheduleRetry();
|
|
758
|
+
}
|
|
759
|
+
throw error;
|
|
760
|
+
|
|
761
|
+
} else if (error instanceof AuthenticationError) {
|
|
762
|
+
// Handle Auth errors
|
|
763
|
+
logError('Authentication failed', error);
|
|
764
|
+
throw error; // Don't retry (already retried 3x)
|
|
765
|
+
|
|
766
|
+
} else if (error instanceof IngestionError) {
|
|
767
|
+
// Handle other ingestion errors
|
|
768
|
+
logError('Ingestion error', error);
|
|
769
|
+
|
|
770
|
+
// Check if retryable
|
|
771
|
+
if (error.isRetryable()) {
|
|
772
|
+
return scheduleRetry();
|
|
773
|
+
}
|
|
774
|
+
throw error;
|
|
775
|
+
|
|
776
|
+
} else {
|
|
777
|
+
// Unknown error
|
|
778
|
+
logError('Unknown error', error);
|
|
779
|
+
throw error;
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
```
|
|
784
|
+
|
|
785
|
+
## Error Object Structure
|
|
786
|
+
|
|
787
|
+
All SDK errors serialize to JSON with this structure:
|
|
788
|
+
|
|
789
|
+
```typescript
|
|
790
|
+
{
|
|
791
|
+
// Basic fields
|
|
792
|
+
name: "MappingError",
|
|
793
|
+
message: "Required field 'ref' is missing or empty",
|
|
794
|
+
|
|
795
|
+
// Error code (for programmatic handling)
|
|
796
|
+
code: "REQUIRED_FIELD_MISSING",
|
|
797
|
+
|
|
798
|
+
// Specific error details
|
|
799
|
+
field: "ref",
|
|
800
|
+
sourcePath: "order.ref",
|
|
801
|
+
|
|
802
|
+
// Additional context
|
|
803
|
+
context: {
|
|
804
|
+
recordIndex: 5,
|
|
805
|
+
fileName: "order-12345.xml",
|
|
806
|
+
mutation: "createOrder"
|
|
807
|
+
},
|
|
808
|
+
|
|
809
|
+
// Tracking
|
|
810
|
+
timestamp: "2025-01-10T12:34:56Z",
|
|
811
|
+
correlationId: "abc-123-def",
|
|
812
|
+
|
|
813
|
+
// Stack trace
|
|
814
|
+
stack: "Error: ...\n at ..."
|
|
815
|
+
}
|
|
816
|
+
```
|
|
817
|
+
|
|
818
|
+
## Key Takeaways
|
|
819
|
+
|
|
820
|
+
- 🎯 **Error hierarchy** - All ingestion errors extend `IngestionError`
|
|
821
|
+
- 🎯 **Error codes** - Use `IngestionErrorCode` enum for programmatic handling
|
|
822
|
+
- 🎯 **Specific classes** - Each error type has specific properties (fileName, field, etc.)
|
|
823
|
+
- 🎯 **Type checking** - Use `instanceof` to handle different error types
|
|
824
|
+
- 🎯 **JSON serialization** - All errors have `toJSON()` for logging
|
|
825
|
+
- 🎯 **Retry detection** - Use `isRetryable()` to determine retry strategy
|
|
826
|
+
|
|
827
|
+
## Practice Exercise
|
|
828
|
+
|
|
829
|
+
Match the error class to the scenario:
|
|
830
|
+
|
|
831
|
+
1. XML file has unclosed tag
|
|
832
|
+
2. Mapping config references non-existent field path
|
|
833
|
+
3. Required field is empty
|
|
834
|
+
4. Network timeout during API call
|
|
835
|
+
5. Missing environment variable
|
|
836
|
+
|
|
837
|
+
<details>
|
|
838
|
+
<summary>Click to see answers</summary>
|
|
839
|
+
|
|
840
|
+
1. `FileParsingError` - Parsing failed
|
|
841
|
+
2. `PathResolutionError` - Path doesn't exist
|
|
842
|
+
3. `MappingError` - Field mapping failed
|
|
843
|
+
4. `BatchSubmissionError` or `IngestionError` with `NETWORK_ERROR` - API error
|
|
844
|
+
5. `ConfigurationError` - Config invalid
|
|
845
|
+
|
|
846
|
+
</details>
|
|
847
|
+
|
|
848
|
+
## Next Steps
|
|
849
|
+
|
|
850
|
+
Continue to [Module 3: UTF-8 Handling →](./error-handling-03-utf8-handling.md) to learn about UTF-8 encoding and special character handling.
|