@fluentcommerce/fc-connect-sdk 0.1.53 → 0.1.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -2
- package/README.md +39 -0
- package/dist/cjs/auth/index.d.ts +3 -0
- package/dist/cjs/auth/index.js +13 -0
- package/dist/cjs/auth/profile-loader.d.ts +18 -0
- package/dist/cjs/auth/profile-loader.js +208 -0
- package/dist/cjs/client-factory.d.ts +4 -0
- package/dist/cjs/client-factory.js +10 -0
- package/dist/cjs/clients/fluent-client.js +13 -6
- package/dist/cjs/index.d.ts +3 -1
- package/dist/cjs/index.js +8 -2
- package/dist/cjs/utils/pagination-helpers.js +38 -2
- package/dist/cjs/versori/fluent-versori-client.js +11 -5
- package/dist/esm/auth/index.d.ts +3 -0
- package/dist/esm/auth/index.js +2 -0
- package/dist/esm/auth/profile-loader.d.ts +18 -0
- package/dist/esm/auth/profile-loader.js +169 -0
- package/dist/esm/client-factory.d.ts +4 -0
- package/dist/esm/client-factory.js +9 -0
- package/dist/esm/clients/fluent-client.js +13 -6
- package/dist/esm/index.d.ts +3 -1
- package/dist/esm/index.js +2 -1
- package/dist/esm/utils/pagination-helpers.js +38 -2
- package/dist/esm/versori/fluent-versori-client.js +11 -5
- package/dist/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/tsconfig.types.tsbuildinfo +1 -1
- package/dist/types/auth/index.d.ts +3 -0
- package/dist/types/auth/profile-loader.d.ts +18 -0
- package/dist/types/client-factory.d.ts +4 -0
- package/dist/types/index.d.ts +3 -1
- package/docs/00-START-HERE/EXPORT-VALIDATION.md +158 -158
- package/docs/00-START-HERE/cli-analyze-source-structure-guide.md +655 -655
- package/docs/00-START-HERE/cli-documentation-index.md +202 -202
- package/docs/00-START-HERE/cli-quick-reference.md +252 -252
- package/docs/00-START-HERE/decision-tree.md +552 -552
- package/docs/00-START-HERE/getting-started.md +1070 -1070
- package/docs/00-START-HERE/mapper-quick-decision-guide.md +235 -235
- package/docs/00-START-HERE/readme.md +237 -237
- package/docs/00-START-HERE/retailerid-configuration.md +404 -404
- package/docs/00-START-HERE/sdk-philosophy.md +794 -794
- package/docs/00-START-HERE/troubleshooting-quick-reference.md +1086 -1086
- package/docs/01-TEMPLATES/faq.md +686 -686
- package/docs/01-TEMPLATES/patterns/pattern-templates-guide.md +68 -68
- package/docs/01-TEMPLATES/patterns/patterns-csv-schema-validation-and-rejection-report.md +233 -233
- package/docs/01-TEMPLATES/patterns/patterns-custom-resolvers.md +407 -407
- package/docs/01-TEMPLATES/patterns/patterns-error-handling-retry.md +511 -511
- package/docs/01-TEMPLATES/patterns/patterns-field-mapping-universal.md +701 -701
- package/docs/01-TEMPLATES/patterns/patterns-large-file-splitting.md +1430 -1430
- package/docs/01-TEMPLATES/patterns/patterns-master-data-etl.md +2399 -2399
- package/docs/01-TEMPLATES/patterns/patterns-pagination-streaming.md +447 -447
- package/docs/01-TEMPLATES/patterns/patterns-state-duplicate-prevention.md +385 -385
- package/docs/01-TEMPLATES/readme.md +957 -957
- package/docs/01-TEMPLATES/standalone/standalone-asn-inbound-processing.md +1209 -1209
- package/docs/01-TEMPLATES/standalone/standalone-graphql-query-export.md +1140 -1140
- package/docs/01-TEMPLATES/standalone/standalone-graphql-to-parquet-partitioned-s3.md +432 -432
- package/docs/01-TEMPLATES/standalone/standalone-multi-channel-inventory-sync.md +1185 -1185
- package/docs/01-TEMPLATES/standalone/standalone-multi-source-aggregation.md +1462 -1462
- package/docs/01-TEMPLATES/standalone/standalone-s3-csv-batch-api.md +1390 -1390
- package/docs/01-TEMPLATES/standalone/standalone-s3-csv-inventory-to-batch.md +330 -330
- package/docs/01-TEMPLATES/standalone/standalone-scripts-guide.md +87 -87
- package/docs/01-TEMPLATES/standalone/standalone-sftp-xml-graphql.md +1444 -1444
- package/docs/01-TEMPLATES/standalone/standalone-webhook-payload-processing.md +688 -688
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-dropship-order-routing.md +193 -193
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-graphql-parquet-extraction.md +518 -518
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-inter-location-transfers.md +2162 -2162
- package/docs/01-TEMPLATES/versori/business-examples/business-examples-pre-order-allocation.md +2226 -2226
- package/docs/01-TEMPLATES/versori/business-examples/business-scenarios-guide.md +87 -87
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-connection-validation-pattern.md +656 -656
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-dual-workflow-connector.md +835 -835
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-guide.md +108 -108
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-kv-state-management.md +1533 -1533
- package/docs/01-TEMPLATES/versori/patterns/versori-patterns-xml-response-patterns.md +1160 -1160
- package/docs/01-TEMPLATES/versori/versori-platform-guide.md +201 -201
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-asn-purchase-order.md +1906 -1906
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-dropship-routing.md +1074 -1074
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-flash-sale-reserve.md +1395 -1395
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-generic-xml-order.md +888 -888
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-payment-gateway-integration.md +2478 -2478
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-rma-returns-comprehensive.md +2240 -2240
- package/docs/01-TEMPLATES/versori/webhooks/template-webhook-xml-order-ingestion.md +2029 -2029
- package/docs/01-TEMPLATES/versori/webhooks/webhook-templates-guide.md +140 -140
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/inventory-mapping.json +20 -20
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/products_2025-01-22.csv +11 -11
- package/docs/01-TEMPLATES/versori/workflows/_examples/sample-data/sample-data-guide.md +34 -34
- package/docs/01-TEMPLATES/versori/workflows/_examples/workflow-examples-guide.md +36 -36
- package/docs/01-TEMPLATES/versori/workflows/extraction/extraction-modes-guide.md +1038 -1038
- package/docs/01-TEMPLATES/versori/workflows/extraction/extraction-workflows-guide.md +138 -138
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/graphql-extraction-guide.md +63 -63
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-fulfillments-to-sftp-csv.md +2062 -2062
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-fulfillments-to-sftp-xml.md +2294 -2294
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-positions-to-s3-csv.md +2461 -2461
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-positions-to-sftp-xml.md +2529 -2529
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-quantities-to-s3-csv.md +2464 -2464
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-inventory-quantities-to-s3-json.md +1959 -1959
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-orders-to-s3-csv.md +1953 -1953
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-orders-to-sftp-xml.md +2541 -2541
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-products-to-s3-json.md +2384 -2384
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-products-to-sftp-xml.md +2445 -2445
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-s3-csv.md +2355 -2355
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-s3-json.md +2042 -2042
- package/docs/01-TEMPLATES/versori/workflows/extraction/graphql-queries/template-extraction-virtual-positions-to-sftp-xml.md +2726 -2726
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/batch-api-guide.md +206 -206
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-cycle-count-reconciliation.md +2030 -2030
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-multi-channel-inventory-sync.md +1882 -1882
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-csv-inventory-batch.md +2827 -2827
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-json-inventory-batch.md +1952 -1952
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-s3-xml-inventory-batch.md +3289 -3289
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-csv-inventory-batch.md +3064 -3064
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-json-inventory-batch.md +3238 -3238
- package/docs/01-TEMPLATES/versori/workflows/ingestion/batch-api/template-ingestion-sftp-xml-inventory-batch.md +2977 -2977
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/event-api-guide.md +321 -321
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-payload-json-order-cancel-event.md +959 -959
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-payload-xml-order-cancel-event.md +1170 -1170
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-csv-product-event.md +2312 -2312
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-json-product-event.md +2999 -2999
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-parquet-product-event.md +2836 -2836
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-s3-xml-product-event.md +2395 -2395
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-csv-product-event.md +2295 -2295
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-json-product-event.md +2602 -2602
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-parquet-product-event.md +2589 -2589
- package/docs/01-TEMPLATES/versori/workflows/ingestion/event-api/template-ingestion-sftp-xml-product-event.md +3578 -3578
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/graphql-mutations-guide.md +93 -93
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-payload-json-order-update-graphql.md +1260 -1260
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-payload-xml-order-update-graphql.md +1472 -1472
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-control-graphql.md +2417 -2417
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-location-graphql.md +2811 -2811
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-csv-price-graphql.md +2619 -2619
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-json-location-graphql.md +2807 -2807
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-s3-xml-location-graphql.md +2373 -2373
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-csv-control-graphql.md +2740 -2740
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-csv-location-graphql.md +2760 -2760
- package/docs/01-TEMPLATES/versori/workflows/ingestion/graphql-mutations/template-ingestion-sftp-json-location-graphql.md +1710 -1710
- package/docs/01-TEMPLATES/versori/workflows/ingestion/ingestion-workflows-guide.md +136 -136
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/rubix-webhooks-guide.md +520 -520
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-fulfilment-to-sftp-xml-inline.md +1418 -1418
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-fulfilment-to-sftp-xml-universal-mapper.md +1785 -1785
- package/docs/01-TEMPLATES/versori/workflows/rubix-webhooks/template-webhook-rubix-order-attribute-update.md +824 -824
- package/docs/01-TEMPLATES/versori/workflows/workflows-overview-guide.md +646 -646
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-batch-archival.md +724 -724
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-job-tracker.md +627 -627
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-partial-batch-recovery.md +561 -561
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-quick-reference.md +367 -367
- package/docs/02-CORE-GUIDES/advanced-services/advanced-services-readme.md +407 -407
- package/docs/02-CORE-GUIDES/advanced-services/readme.md +49 -49
- package/docs/02-CORE-GUIDES/api-reference/api-reference-quick-reference.md +548 -548
- package/docs/02-CORE-GUIDES/api-reference/event-api-input-output-reference.md +702 -1171
- package/docs/02-CORE-GUIDES/api-reference/examples/client-initialization.ts +286 -286
- package/docs/02-CORE-GUIDES/api-reference/graphql-error-classification.md +337 -337
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-01-client-api.md +399 -482
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-03-authentication.md +199 -199
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-04-graphql-mapping.md +925 -925
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-05-services.md +1198 -1198
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-06-data-sources.md +1083 -1083
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-07-parsers.md +1097 -1097
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-08-pagination.md +513 -513
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-08-types.md +545 -597
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-09-error-handling.md +527 -527
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-09-webhook-validation.md +514 -514
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-10-extraction.md +557 -557
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-10-utilities.md +412 -412
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-11-cli-tools.md +423 -423
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-11-error-handling.md +716 -716
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-analyze-source-structure.md +518 -518
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-partial-responses.md +212 -212
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-12-testing.md +300 -300
- package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-13-resolver-builder.md +322 -322
- package/docs/02-CORE-GUIDES/api-reference/readme.md +279 -279
- package/docs/02-CORE-GUIDES/auto-pagination/auto-pagination-quick-reference.md +351 -351
- package/docs/02-CORE-GUIDES/auto-pagination/auto-pagination-readme.md +277 -277
- package/docs/02-CORE-GUIDES/auto-pagination/examples/auto-pagination-readme.md +178 -178
- package/docs/02-CORE-GUIDES/auto-pagination/examples/common-patterns.ts +351 -351
- package/docs/02-CORE-GUIDES/auto-pagination/examples/paginate-products.ts +384 -384
- package/docs/02-CORE-GUIDES/auto-pagination/examples/paginate-virtual-positions.ts +308 -308
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-01-foundations.md +470 -470
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-02-quick-start.md +713 -713
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-03-configuration.md +754 -754
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-04-advanced-patterns.md +732 -732
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-05-sdk-integration.md +847 -847
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-06-troubleshooting.md +359 -359
- package/docs/02-CORE-GUIDES/auto-pagination/modules/auto-pagination-07-api-reference.md +462 -462
- package/docs/02-CORE-GUIDES/auto-pagination/readme.md +54 -54
- package/docs/02-CORE-GUIDES/data-sources/data-sources-file-operations-error-handling.md +1487 -1487
- package/docs/02-CORE-GUIDES/data-sources/data-sources-quick-reference.md +836 -836
- package/docs/02-CORE-GUIDES/data-sources/data-sources-readme.md +276 -276
- package/docs/02-CORE-GUIDES/data-sources/data-sources-sftp-credential-access-security.md +553 -553
- package/docs/02-CORE-GUIDES/data-sources/examples/common-patterns.ts +409 -409
- package/docs/02-CORE-GUIDES/data-sources/examples/data-sources-readme.md +178 -178
- package/docs/02-CORE-GUIDES/data-sources/examples/s3-operations.ts +308 -308
- package/docs/02-CORE-GUIDES/data-sources/examples/sftp-operations.ts +371 -371
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-01-foundations.md +735 -735
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-02-s3-operations.md +1302 -1302
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-03-sftp-operations.md +1379 -1379
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-04-file-patterns.md +941 -941
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-05-advanced-topics.md +813 -813
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-06-integration-patterns.md +486 -486
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-07-troubleshooting.md +387 -387
- package/docs/02-CORE-GUIDES/data-sources/modules/data-sources-08-api-reference.md +417 -417
- package/docs/02-CORE-GUIDES/data-sources/readme.md +77 -77
- package/docs/02-CORE-GUIDES/error-handling-guide.md +936 -936
- package/docs/02-CORE-GUIDES/extraction/examples/02-core-guides-extraction-readme.md +116 -116
- package/docs/02-CORE-GUIDES/extraction/examples/common-patterns.ts +428 -428
- package/docs/02-CORE-GUIDES/extraction/examples/extract-inventory-basic.ts +187 -187
- package/docs/02-CORE-GUIDES/extraction/extraction-quick-reference.md +596 -596
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-01-foundations.md +514 -514
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-02-basic-extraction.md +823 -823
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-03-parquet-processing.md +507 -507
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-04-data-enrichment.md +546 -546
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-05-transformation.md +494 -494
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-06-export-formats.md +458 -458
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-06-performance.md +138 -138
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-07-api-reference.md +148 -148
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-07-optimization.md +692 -692
- package/docs/02-CORE-GUIDES/extraction/modules/02-core-guides-extraction-08-extraction-orchestrator.md +1008 -1008
- package/docs/02-CORE-GUIDES/extraction/readme.md +151 -151
- package/docs/02-CORE-GUIDES/ingestion/examples/_simple-kv-store.ts +40 -40
- package/docs/02-CORE-GUIDES/ingestion/examples/error-recovery.ts +728 -728
- package/docs/02-CORE-GUIDES/ingestion/examples/event-driven.ts +501 -501
- package/docs/02-CORE-GUIDES/ingestion/examples/local-file-ingestion.ts +88 -88
- package/docs/02-CORE-GUIDES/ingestion/examples/parquet-ingestion.ts +117 -117
- package/docs/02-CORE-GUIDES/ingestion/examples/performance-optimized.ts +647 -647
- package/docs/02-CORE-GUIDES/ingestion/examples/s3-csv-ingestion.ts +169 -169
- package/docs/02-CORE-GUIDES/ingestion/examples/sftp-csv-ingestion.ts +134 -134
- package/docs/02-CORE-GUIDES/ingestion/ingestion-quick-reference.md +546 -546
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-01-introduction.md +626 -626
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-02-quick-start.md +658 -658
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-03-data-sources.md +1052 -1052
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-04-field-mapping.md +763 -763
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-05-advanced-parsers.md +676 -676
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-06-batch-api.md +1295 -1295
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-07-api-reference.md +138 -138
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-07-state-management.md +1037 -1037
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-08-performance-optimization.md +1349 -1349
- package/docs/02-CORE-GUIDES/ingestion/modules/02-core-guides-ingestion-09-best-practices.md +1893 -1893
- package/docs/02-CORE-GUIDES/ingestion/readme.md +160 -160
- package/docs/02-CORE-GUIDES/logging-guide.md +585 -585
- package/docs/02-CORE-GUIDES/mapping/error-handling-patterns.md +401 -401
- package/docs/02-CORE-GUIDES/mapping/examples/02-core-guides-mapping-readme.md +128 -128
- package/docs/02-CORE-GUIDES/mapping/examples/common-patterns.ts +273 -273
- package/docs/02-CORE-GUIDES/mapping/examples/csv-location-ingestion.json +36 -36
- package/docs/02-CORE-GUIDES/mapping/examples/csv-mapping.ts +242 -242
- package/docs/02-CORE-GUIDES/mapping/examples/graphql-to-parquet-extraction.json +36 -36
- package/docs/02-CORE-GUIDES/mapping/examples/json-mapping.ts +213 -213
- package/docs/02-CORE-GUIDES/mapping/examples/json-product-to-mutation.json +48 -48
- package/docs/02-CORE-GUIDES/mapping/examples/xml-mapping.ts +291 -291
- package/docs/02-CORE-GUIDES/mapping/examples/xml-order-to-mutation.json +45 -45
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/graphql-mutation-mapping-quick-reference.md +463 -463
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/graphql-mutation-mapping-readme.md +227 -227
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-01-introduction.md +222 -222
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-02-quick-start.md +351 -351
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-03-schema-validation.md +569 -569
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-04-mapping-patterns.md +471 -471
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-05-configuration-reference.md +611 -611
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-06-advanced-xpath.md +148 -148
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-06-path-syntax.md +464 -464
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-07-api-reference.md +94 -94
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-07-array-handling.md +307 -307
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-08-custom-resolvers.md +544 -544
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-09-advanced-patterns.md +427 -427
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-10-hooks-and-variables.md +336 -336
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-11-error-handling.md +488 -488
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-12-arguments-vs-nodes.md +383 -383
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/modules/graphql-mutation-mapping-13-best-practices.md +477 -477
- package/docs/02-CORE-GUIDES/mapping/graphql-mutation-mapping/readme.md +62 -62
- package/docs/02-CORE-GUIDES/mapping/mapping-format-decision-tree.md +480 -480
- package/docs/02-CORE-GUIDES/mapping/mapping-graphql-alias-batching-guide.md +820 -820
- package/docs/02-CORE-GUIDES/mapping/mapping-javascript-objects.md +2369 -2369
- package/docs/02-CORE-GUIDES/mapping/mapping-mapper-comparison-guide.md +682 -682
- package/docs/02-CORE-GUIDES/mapping/modules/02-core-guides-mapping-07-api-reference.md +1327 -1327
- package/docs/02-CORE-GUIDES/mapping/modules/02-core-guides-mapping-08-error-handling.md +1142 -1142
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-04-use-cases.md +891 -891
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-06-helpers-resolvers.md +1126 -1126
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-06-sdk-resolvers.md +199 -199
- package/docs/02-CORE-GUIDES/mapping/modules/mapping-07-api-reference.md +1319 -1319
- package/docs/02-CORE-GUIDES/mapping/readme.md +178 -178
- package/docs/02-CORE-GUIDES/mapping/resolver-registration.md +410 -410
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/common-patterns.ts +226 -226
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/custom-resolvers.ts +227 -227
- package/docs/02-CORE-GUIDES/mapping/resolvers/examples/sdk-resolvers-usage.ts +203 -203
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-readme.md +274 -274
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-api-reference.md +679 -679
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-cookbook.md +826 -826
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-guide.md +1330 -1330
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-helpers-reference.md +1437 -1437
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-parameters-reference.md +553 -553
- package/docs/02-CORE-GUIDES/mapping/resolvers/mapping-resolvers-resolver-troubleshooting.md +854 -854
- package/docs/02-CORE-GUIDES/mapping/resolvers/readme.md +75 -75
- package/docs/02-CORE-GUIDES/parsers/examples/02-core-guides-parsers-readme.md +161 -161
- package/docs/02-CORE-GUIDES/parsers/examples/csv-parser-examples.ts +110 -110
- package/docs/02-CORE-GUIDES/parsers/examples/json-parser-examples.ts +33 -33
- package/docs/02-CORE-GUIDES/parsers/examples/parquet-parser-examples.ts +47 -47
- package/docs/02-CORE-GUIDES/parsers/examples/xml-parser-examples.ts +38 -38
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-01-foundations.md +355 -355
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-02-csv-parser.md +772 -772
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-03-json-parser.md +789 -789
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-04-xml-parser.md +857 -857
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-05-parquet-parser.md +603 -603
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-06-integration-patterns.md +702 -702
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-06-streaming.md +121 -121
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-07-api-reference.md +89 -89
- package/docs/02-CORE-GUIDES/parsers/modules/02-core-guides-parsers-07-troubleshooting.md +727 -727
- package/docs/02-CORE-GUIDES/parsers/parsers-quick-reference.md +482 -482
- package/docs/02-CORE-GUIDES/parsers/parsers-readme.md +258 -258
- package/docs/02-CORE-GUIDES/parsers/readme.md +65 -65
- package/docs/02-CORE-GUIDES/readme.md +194 -194
- package/docs/02-CORE-GUIDES/webhook-validation/examples/basic-validation.ts +108 -108
- package/docs/02-CORE-GUIDES/webhook-validation/examples/common-patterns.ts +316 -316
- package/docs/02-CORE-GUIDES/webhook-validation/examples/webhook-validation-readme.md +61 -61
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-01-foundations.md +440 -440
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-02-quick-start.md +525 -525
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-03-versori-integration.md +741 -741
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-04-platform-integration.md +629 -629
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-05-configuration.md +535 -535
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-06-error-handling.md +611 -611
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-06-troubleshooting.md +124 -124
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-07-api-reference.md +511 -511
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-08-rubix-webhooks.md +590 -590
- package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-09-rubix-event-vs-http-call.md +432 -432
- package/docs/02-CORE-GUIDES/webhook-validation/readme.md +239 -239
- package/docs/02-CORE-GUIDES/webhook-validation/webhook-validation-quick-reference.md +392 -392
- package/docs/03-PATTERN-GUIDES/connector-scenarios/connector-scenarios-quick-reference.md +498 -498
- package/docs/03-PATTERN-GUIDES/connector-scenarios/connector-scenarios-readme.md +313 -313
- package/docs/03-PATTERN-GUIDES/connector-scenarios/examples/common-patterns.ts +612 -612
- package/docs/03-PATTERN-GUIDES/connector-scenarios/examples/connector-scenarios-readme.md +253 -253
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-01-foundations.md +452 -452
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-02-simple-scenarios.md +681 -681
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-03-intermediate-scenarios.md +637 -637
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-04-advanced-scenarios.md +650 -650
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-05-bidirectional-sync.md +233 -233
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-06-production-patterns.md +442 -442
- package/docs/03-PATTERN-GUIDES/connector-scenarios/modules/connector-scenarios-07-reference.md +445 -445
- package/docs/03-PATTERN-GUIDES/connector-scenarios/readme.md +31 -31
- package/docs/03-PATTERN-GUIDES/enterprise-integration-patterns.md +1528 -1528
- package/docs/03-PATTERN-GUIDES/error-handling/comprehensive-error-handling-guide.md +1437 -1437
- package/docs/03-PATTERN-GUIDES/error-handling/error-handling-quick-reference.md +390 -390
- package/docs/03-PATTERN-GUIDES/error-handling/examples/common-patterns.ts +438 -438
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-01-foundations.md +362 -362
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-02-error-types.md +850 -850
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-03-utf8-handling.md +456 -456
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-04-error-scenarios.md +658 -658
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-05-calling-patterns.md +671 -671
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-06-retry-strategies.md +1034 -1034
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-07-monitoring.md +653 -653
- package/docs/03-PATTERN-GUIDES/error-handling/modules/error-handling-08-api-reference.md +847 -847
- package/docs/03-PATTERN-GUIDES/error-handling/readme.md +36 -36
- package/docs/03-PATTERN-GUIDES/examples/__tests__/readme.md +40 -40
- package/docs/03-PATTERN-GUIDES/examples/__tests__/resolver-examples.test.js +282 -282
- package/docs/03-PATTERN-GUIDES/examples/test-data/03-pattern-guides-readme.md +110 -110
- package/docs/03-PATTERN-GUIDES/examples/test-data/canonical-inventory.json +123 -123
- package/docs/03-PATTERN-GUIDES/examples/test-data/canonical-order.json +171 -171
- package/docs/03-PATTERN-GUIDES/examples/test-data/readme.md +28 -28
- package/docs/03-PATTERN-GUIDES/extraction/extraction-readme.md +15 -15
- package/docs/03-PATTERN-GUIDES/extraction/readme.md +25 -25
- package/docs/03-PATTERN-GUIDES/file-operations/examples/common-patterns.ts +407 -407
- package/docs/03-PATTERN-GUIDES/file-operations/examples/file-operations-readme.md +142 -142
- package/docs/03-PATTERN-GUIDES/file-operations/file-operations-quick-reference.md +462 -462
- package/docs/03-PATTERN-GUIDES/file-operations/file-operations-readme.md +379 -379
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-01-foundations.md +430 -430
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-02-quick-start.md +484 -484
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-03-s3-operations.md +507 -507
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-04-sftp-operations.md +963 -963
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-05-streaming-performance.md +503 -503
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-06-archive-patterns.md +386 -386
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-06-error-handling.md +117 -117
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-07-api-reference.md +78 -78
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-07-testing-troubleshooting.md +567 -567
- package/docs/03-PATTERN-GUIDES/file-operations/modules/file-operations-08-api-reference.md +1055 -1055
- package/docs/03-PATTERN-GUIDES/file-operations/readme.md +32 -32
- package/docs/03-PATTERN-GUIDES/ingestion/ingestion-readme.md +15 -15
- package/docs/03-PATTERN-GUIDES/ingestion/readme.md +25 -25
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/batch-processing.ts +130 -130
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/common-patterns.ts +360 -360
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/delta-sync.ts +130 -130
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/integration-patterns-readme.md +100 -100
- package/docs/03-PATTERN-GUIDES/integration-patterns/examples/real-time-webhook.ts +398 -398
- package/docs/03-PATTERN-GUIDES/integration-patterns/integration-patterns-quick-reference.md +962 -962
- package/docs/03-PATTERN-GUIDES/integration-patterns/integration-patterns-readme.md +134 -134
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-01-real-time-processing.md +991 -991
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-02-batch-processing.md +1547 -1547
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-03-delta-sync.md +1108 -1108
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-04-webhook-patterns.md +1181 -1181
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-05-error-handling.md +1061 -1061
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-06-advanced-integration-services.md +1547 -1547
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-06-performance.md +109 -109
- package/docs/03-PATTERN-GUIDES/integration-patterns/modules/integration-patterns-07-api-reference.md +34 -34
- package/docs/03-PATTERN-GUIDES/integration-patterns/readme.md +30 -30
- package/docs/03-PATTERN-GUIDES/logging-minimal-mode.md +128 -128
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/common-patterns.ts +380 -380
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/multiple-connections-readme.md +139 -139
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/parallel-root-connections.ts +149 -149
- package/docs/03-PATTERN-GUIDES/multiple-connections/examples/real-world-scenarios.ts +405 -405
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-01-foundations.md +378 -378
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-02-quick-start.md +566 -566
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-03-targeting-connections.md +659 -659
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-04-parallel-queries.md +656 -656
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-05-best-practices.md +624 -624
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-06-api-reference.md +824 -824
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-06-versori.md +119 -119
- package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-07-api-reference.md +87 -87
- package/docs/03-PATTERN-GUIDES/multiple-connections/multiple-connections-quick-reference.md +353 -353
- package/docs/03-PATTERN-GUIDES/multiple-connections/multiple-connections-readme.md +270 -270
- package/docs/03-PATTERN-GUIDES/multiple-connections/readme.md +30 -30
- package/docs/03-PATTERN-GUIDES/pagination/pagination-readme.md +14 -14
- package/docs/03-PATTERN-GUIDES/pagination/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/parquet/examples/common-patterns.ts +180 -180
- package/docs/03-PATTERN-GUIDES/parquet/examples/read-parquet.ts +48 -48
- package/docs/03-PATTERN-GUIDES/parquet/examples/write-parquet.ts +65 -65
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-01-introduction.md +393 -393
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-02-quick-start.md +572 -572
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-03-reading-parquet.md +525 -525
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-04-writing-parquet.md +554 -554
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-05-graphql-extraction.md +405 -405
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-06-performance.md +104 -104
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-06-s3-integration.md +511 -511
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-07-api-reference.md +90 -90
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-07-performance-optimization.md +525 -525
- package/docs/03-PATTERN-GUIDES/parquet/modules/03-pattern-guides-parquet-08-best-practices.md +712 -712
- package/docs/03-PATTERN-GUIDES/parquet/parquet-quick-reference.md +683 -683
- package/docs/03-PATTERN-GUIDES/parquet/parquet-readme.md +248 -248
- package/docs/03-PATTERN-GUIDES/parquet/readme.md +32 -32
- package/docs/03-PATTERN-GUIDES/parsers/parsers-readme.md +12 -12
- package/docs/03-PATTERN-GUIDES/parsers/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/readme.md +159 -159
- package/docs/03-PATTERN-GUIDES/webhooks/readme.md +24 -24
- package/docs/03-PATTERN-GUIDES/webhooks/webhooks-readme.md +8 -8
- package/docs/04-REFERENCE/architecture/architecture-01-overview.md +427 -427
- package/docs/04-REFERENCE/architecture/architecture-02-client-architecture.md +424 -424
- package/docs/04-REFERENCE/architecture/architecture-03-data-flow.md +690 -690
- package/docs/04-REFERENCE/architecture/architecture-04-service-layer.md +834 -834
- package/docs/04-REFERENCE/architecture/architecture-05-integration-architecture.md +655 -655
- package/docs/04-REFERENCE/architecture/architecture-06-state-management.md +653 -653
- package/docs/04-REFERENCE/architecture/architecture-adding-new-data-sources.md +686 -686
- package/docs/04-REFERENCE/architecture/readme.md +279 -279
- package/docs/04-REFERENCE/platforms/deno/readme.md +117 -117
- package/docs/04-REFERENCE/platforms/nodejs/readme.md +146 -146
- package/docs/04-REFERENCE/platforms/readme.md +135 -135
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-01-introduction.md +398 -398
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-02-quick-start.md +560 -560
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-03-authentication.md +757 -757
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-04-workflows.md +2476 -2476
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-05-connections.md +1167 -1167
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-06-kv-storage.md +990 -990
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-06-state-management.md +121 -121
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-07-api-reference.md +68 -68
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-07-deployment.md +731 -731
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-08-best-practices.md +1111 -1111
- package/docs/04-REFERENCE/platforms/versori/modules/platforms-versori-09-signature-reference.md +766 -766
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-readme.md +299 -299
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-s3-sftp-configuration-guide.md +1425 -1425
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-webhook-api-key-security.md +816 -816
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-webhook-connection-security.md +681 -681
- package/docs/04-REFERENCE/platforms/versori/platforms-versori-workflow-task-types.md +708 -708
- package/docs/04-REFERENCE/platforms/versori/readme.md +108 -108
- package/docs/04-REFERENCE/readme.md +148 -148
- package/docs/04-REFERENCE/resolver-signature/examples/advanced-resolvers.ts +482 -482
- package/docs/04-REFERENCE/resolver-signature/examples/async-resolvers.ts +496 -496
- package/docs/04-REFERENCE/resolver-signature/examples/basic-resolvers.ts +343 -343
- package/docs/04-REFERENCE/resolver-signature/examples/resolver-signature-readme.md +188 -188
- package/docs/04-REFERENCE/resolver-signature/examples/testing-resolvers.ts +463 -463
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-01-foundations.md +286 -286
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-02-parameter-reference.md +643 -643
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-03-basic-examples.md +521 -521
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-04-advanced-patterns.md +739 -739
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-05-sdk-resolvers.md +531 -531
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-06-migration-guide.md +650 -650
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-06-testing.md +125 -125
- package/docs/04-REFERENCE/resolver-signature/modules/resolver-signature-07-api-reference.md +794 -794
- package/docs/04-REFERENCE/resolver-signature/readme.md +64 -64
- package/docs/04-REFERENCE/resolver-signature/resolver-signature-quick-reference.md +270 -270
- package/docs/04-REFERENCE/resolver-signature/resolver-signature-readme.md +351 -351
- package/docs/04-REFERENCE/schema/fluent-commerce-schema.json +764 -764
- package/docs/04-REFERENCE/schema/readme.md +141 -141
- package/docs/04-REFERENCE/testing/examples/04-reference-testing-readme.md +158 -158
- package/docs/04-REFERENCE/testing/examples/fluent-testing.ts +62 -62
- package/docs/04-REFERENCE/testing/examples/health-check.ts +155 -155
- package/docs/04-REFERENCE/testing/examples/integration-test.ts +119 -119
- package/docs/04-REFERENCE/testing/examples/performance-test.ts +183 -183
- package/docs/04-REFERENCE/testing/examples/s3-testing.ts +127 -127
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-01-foundations.md +267 -267
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-02-s3-testing.md +599 -599
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-03-fluent-testing.md +589 -589
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-04-integration-testing.md +699 -699
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-05-debugging.md +478 -478
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-06-cicd-integration.md +463 -463
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-06-preflight-validation.md +131 -131
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-07-best-practices.md +499 -499
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-07-coverage-ci.md +165 -165
- package/docs/04-REFERENCE/testing/modules/04-reference-testing-08-api-reference.md +634 -634
- package/docs/04-REFERENCE/testing/readme.md +86 -86
- package/docs/04-REFERENCE/testing/testing-quick-reference.md +667 -667
- package/docs/04-REFERENCE/testing/testing-readme.md +286 -286
- package/docs/04-REFERENCE/troubleshooting/readme.md +144 -144
- package/docs/04-REFERENCE/troubleshooting/troubleshooting-deno-sftp-compatibility.md +392 -392
- package/docs/template-loading-matrix.md +242 -242
- package/package.json +5 -3
|
@@ -1,847 +1,847 @@
|
|
|
1
|
-
# Module 8: API Reference
|
|
2
|
-
|
|
3
|
-
**Level:** Reference
|
|
4
|
-
**Estimated Time:** As needed
|
|
5
|
-
|
|
6
|
-
## Overview
|
|
7
|
-
|
|
8
|
-
This module provides complete API documentation for all error classes, error codes, and best practices for error handling in the SDK.
|
|
9
|
-
|
|
10
|
-
## Error Class Reference
|
|
11
|
-
|
|
12
|
-
### IngestionError (Base Class)
|
|
13
|
-
|
|
14
|
-
Base class for all ingestion-related errors.
|
|
15
|
-
|
|
16
|
-
```typescript
|
|
17
|
-
abstract class IngestionError extends Error {
|
|
18
|
-
readonly code: IngestionErrorCode;
|
|
19
|
-
readonly context?: Record<string, any>;
|
|
20
|
-
readonly timestamp: Date;
|
|
21
|
-
readonly correlationId?: string;
|
|
22
|
-
|
|
23
|
-
constructor(
|
|
24
|
-
message: string,
|
|
25
|
-
code: IngestionErrorCode,
|
|
26
|
-
context?: Record<string, any>,
|
|
27
|
-
correlationId?: string
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
toJSON(): Record<string, any>;
|
|
31
|
-
isRetryable(): boolean;
|
|
32
|
-
}
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
**Properties:**
|
|
36
|
-
- `code`: Machine-readable error code from `IngestionErrorCode` enum
|
|
37
|
-
- `context`: Additional error context (file name, record index, etc.)
|
|
38
|
-
- `timestamp`: When the error occurred
|
|
39
|
-
- `correlationId`: For tracking errors across distributed systems
|
|
40
|
-
- `message`: Human-readable error description
|
|
41
|
-
- `name`: Error class name
|
|
42
|
-
- `stack`: Stack trace
|
|
43
|
-
|
|
44
|
-
**Methods:**
|
|
45
|
-
|
|
46
|
-
#### toJSON()
|
|
47
|
-
|
|
48
|
-
Serializes error to JSON for logging:
|
|
49
|
-
|
|
50
|
-
```typescript
|
|
51
|
-
const error = new FileParsingError('Invalid XML', 'order.xml', 42);
|
|
52
|
-
const json = error.toJSON();
|
|
53
|
-
// {
|
|
54
|
-
// name: 'FileParsingError',
|
|
55
|
-
// message: 'Invalid XML',
|
|
56
|
-
// code: 'PARSE_ERROR',
|
|
57
|
-
// fileName: 'order.xml',
|
|
58
|
-
// lineNumber: 42,
|
|
59
|
-
// timestamp: '2025-01-10T12:34:56.789Z',
|
|
60
|
-
// stack: '...'
|
|
61
|
-
// }
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
#### isRetryable()
|
|
65
|
-
|
|
66
|
-
Determines if error should be retried:
|
|
67
|
-
|
|
68
|
-
```typescript
|
|
69
|
-
if (error.isRetryable()) {
|
|
70
|
-
// Retry with exponential backoff
|
|
71
|
-
await retryOperation();
|
|
72
|
-
} else {
|
|
73
|
-
// Permanent failure - don't retry
|
|
74
|
-
throw error;
|
|
75
|
-
}
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
**Retryable codes:**
|
|
79
|
-
- `NETWORK_ERROR`
|
|
80
|
-
- `TIMEOUT_ERROR`
|
|
81
|
-
- `RATE_LIMIT_ERROR`
|
|
82
|
-
- `LOCK_ACQUISITION_FAILED`
|
|
83
|
-
|
|
84
|
-
### FileDiscoveryError
|
|
85
|
-
|
|
86
|
-
Thrown when file discovery or access fails.
|
|
87
|
-
|
|
88
|
-
```typescript
|
|
89
|
-
class FileDiscoveryError extends IngestionError {
|
|
90
|
-
readonly fileName?: string;
|
|
91
|
-
readonly path?: string;
|
|
92
|
-
}
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
**Example:**
|
|
96
|
-
|
|
97
|
-
```typescript
|
|
98
|
-
throw new FileDiscoveryError(
|
|
99
|
-
'Failed to list S3 bucket',
|
|
100
|
-
IngestionErrorCode.FILE_DISCOVERY_FAILED,
|
|
101
|
-
{ bucket: 's3://my-bucket', prefix: 'orders/' }
|
|
102
|
-
);
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
### FileParsingError
|
|
106
|
-
|
|
107
|
-
Thrown when file parsing fails.
|
|
108
|
-
|
|
109
|
-
```typescript
|
|
110
|
-
class FileParsingError extends IngestionError {
|
|
111
|
-
readonly fileName?: string;
|
|
112
|
-
readonly lineNumber?: number;
|
|
113
|
-
}
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
**Example:**
|
|
117
|
-
|
|
118
|
-
```typescript
|
|
119
|
-
throw new FileParsingError(
|
|
120
|
-
'Unclosed XML tag',
|
|
121
|
-
'order-123.xml',
|
|
122
|
-
42, // line number
|
|
123
|
-
{ tag: 'customer', position: 1234 }
|
|
124
|
-
);
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
**Common scenarios:**
|
|
128
|
-
- Invalid XML syntax
|
|
129
|
-
- Malformed JSON
|
|
130
|
-
- CSV column mismatch
|
|
131
|
-
- Corrupted Parquet file
|
|
132
|
-
|
|
133
|
-
### TransformationError
|
|
134
|
-
|
|
135
|
-
Thrown during data transformation.
|
|
136
|
-
|
|
137
|
-
```typescript
|
|
138
|
-
class TransformationError extends IngestionError {
|
|
139
|
-
readonly recordIndex?: number;
|
|
140
|
-
readonly fieldName?: string;
|
|
141
|
-
}
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
**Example:**
|
|
145
|
-
|
|
146
|
-
```typescript
|
|
147
|
-
throw new TransformationError(
|
|
148
|
-
'Failed to parse date',
|
|
149
|
-
IngestionErrorCode.TRANSFORMATION_ERROR,
|
|
150
|
-
{
|
|
151
|
-
recordIndex: 5,
|
|
152
|
-
fieldName: 'orderDate',
|
|
153
|
-
value: 'invalid-date'
|
|
154
|
-
}
|
|
155
|
-
);
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
### BatchSubmissionError
|
|
159
|
-
|
|
160
|
-
Thrown when Batch API submission fails.
|
|
161
|
-
|
|
162
|
-
```typescript
|
|
163
|
-
class BatchSubmissionError extends IngestionError {
|
|
164
|
-
readonly jobId?: string;
|
|
165
|
-
readonly batchId?: string;
|
|
166
|
-
}
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
**Example:**
|
|
170
|
-
|
|
171
|
-
```typescript
|
|
172
|
-
throw new BatchSubmissionError(
|
|
173
|
-
'Batch submission failed',
|
|
174
|
-
IngestionErrorCode.BATCH_SUBMISSION_ERROR,
|
|
175
|
-
{
|
|
176
|
-
jobId: 'JOB-123',
|
|
177
|
-
batchId: 'BATCH-456',
|
|
178
|
-
statusCode: 500
|
|
179
|
-
}
|
|
180
|
-
);
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### ConfigurationError
|
|
184
|
-
|
|
185
|
-
Thrown when SDK configuration is invalid.
|
|
186
|
-
|
|
187
|
-
```typescript
|
|
188
|
-
class ConfigurationError extends IngestionError {
|
|
189
|
-
readonly configKey?: string;
|
|
190
|
-
}
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
**Example:**
|
|
194
|
-
|
|
195
|
-
```typescript
|
|
196
|
-
throw new ConfigurationError(
|
|
197
|
-
'Missing required configuration',
|
|
198
|
-
IngestionErrorCode.MISSING_REQUIRED_CONFIG,
|
|
199
|
-
{ configKey: 'FLUENT_CLIENT_ID' }
|
|
200
|
-
);
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
### ValidationError
|
|
204
|
-
|
|
205
|
-
Thrown when data validation fails.
|
|
206
|
-
|
|
207
|
-
```typescript
|
|
208
|
-
class ValidationError extends IngestionError {
|
|
209
|
-
readonly validationErrors: Array<{
|
|
210
|
-
field?: string;
|
|
211
|
-
value?: any;
|
|
212
|
-
rule?: string;
|
|
213
|
-
message: string;
|
|
214
|
-
}>;
|
|
215
|
-
}
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
**Example:**
|
|
219
|
-
|
|
220
|
-
```typescript
|
|
221
|
-
throw new ValidationError(
|
|
222
|
-
'Validation failed',
|
|
223
|
-
[
|
|
224
|
-
{
|
|
225
|
-
field: 'email',
|
|
226
|
-
value: 'invalid-email',
|
|
227
|
-
rule: 'email_format',
|
|
228
|
-
message: 'Invalid email format'
|
|
229
|
-
},
|
|
230
|
-
{
|
|
231
|
-
field: 'quantity',
|
|
232
|
-
value: -5,
|
|
233
|
-
rule: 'min_value',
|
|
234
|
-
message: 'Quantity must be positive'
|
|
235
|
-
}
|
|
236
|
-
]
|
|
237
|
-
);
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
### AggregateIngestionError
|
|
241
|
-
|
|
242
|
-
Thrown when multiple errors occur during batch processing.
|
|
243
|
-
|
|
244
|
-
```typescript
|
|
245
|
-
class AggregateIngestionError extends IngestionError {
|
|
246
|
-
readonly errors: IngestionError[];
|
|
247
|
-
|
|
248
|
-
getAllCodes(): IngestionErrorCode[];
|
|
249
|
-
hasRetryableError(): boolean;
|
|
250
|
-
getErrorsByCode(code: IngestionErrorCode): IngestionError[];
|
|
251
|
-
}
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
**Example:**
|
|
255
|
-
|
|
256
|
-
```typescript
|
|
257
|
-
const errors = [
|
|
258
|
-
new FileParsingError('Invalid XML', 'order-1.xml', 10),
|
|
259
|
-
new FileParsingError('Invalid XML', 'order-2.xml', 20)
|
|
260
|
-
];
|
|
261
|
-
|
|
262
|
-
throw new AggregateIngestionError(
|
|
263
|
-
`${errors.length} files failed processing`,
|
|
264
|
-
errors,
|
|
265
|
-
{ batchId: 'BATCH-123' }
|
|
266
|
-
);
|
|
267
|
-
|
|
268
|
-
// Check if any errors are retryable
|
|
269
|
-
if (aggregateError.hasRetryableError()) {
|
|
270
|
-
// Retry the batch
|
|
271
|
-
}
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
## New Services for Error Recovery
|
|
275
|
-
|
|
276
|
-
### PartialBatchRecovery
|
|
277
|
-
|
|
278
|
-
Service for handling partial batch failures with automatic recovery.
|
|
279
|
-
|
|
280
|
-
**Purpose:** Retry only failed records instead of entire batches, reducing overhead and improving efficiency.
|
|
281
|
-
|
|
282
|
-
```typescript
|
|
283
|
-
class PartialBatchRecovery {
|
|
284
|
-
constructor(logger: Logger);
|
|
285
|
-
|
|
286
|
-
async processBatchWithRecovery<T>(
|
|
287
|
-
records: T[],
|
|
288
|
-
processFn: (batch: T[]) => Promise<any>,
|
|
289
|
-
options?: RecoveryOptions
|
|
290
|
-
): Promise<RecoveryResult>;
|
|
291
|
-
}
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
**Options:**
|
|
295
|
-
|
|
296
|
-
```typescript
|
|
297
|
-
interface RecoveryOptions {
|
|
298
|
-
maxRetries?: number; // Max retry attempts per record (default: 3)
|
|
299
|
-
retryOnlyFailed?: boolean; // Only retry failed records (default: true)
|
|
300
|
-
batchSize?: number; // Batch size for processing (default: 100)
|
|
301
|
-
retryDelay?: number; // Delay between retries in ms (default: 1000)
|
|
302
|
-
exponentialBackoff?: boolean; // Use exponential backoff (default: true)
|
|
303
|
-
shouldRetry?: (error: Error, attempt: number) => boolean;
|
|
304
|
-
calculateDelay?: (attempt: number, baseDelay: number) => number;
|
|
305
|
-
onProgress?: (current: number, total: number) => void;
|
|
306
|
-
onRetry?: (record: any, attempt: number, error: Error) => void;
|
|
307
|
-
}
|
|
308
|
-
```
|
|
309
|
-
|
|
310
|
-
**Return Value:**
|
|
311
|
-
|
|
312
|
-
```typescript
|
|
313
|
-
interface RecoveryResult {
|
|
314
|
-
successCount: number;
|
|
315
|
-
failedCount: number;
|
|
316
|
-
failedRecords: Array<{
|
|
317
|
-
record: any;
|
|
318
|
-
error: Error;
|
|
319
|
-
attemptCount: number;
|
|
320
|
-
}>;
|
|
321
|
-
}
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
**Example:**
|
|
325
|
-
|
|
326
|
-
```typescript
|
|
327
|
-
import {
|
|
328
|
-
PartialBatchRecovery,
|
|
329
|
-
createClient,
|
|
330
|
-
createConsoleLogger,
|
|
331
|
-
toStructuredLogger
|
|
332
|
-
} from '@fluentcommerce/fc-connect-sdk';
|
|
333
|
-
|
|
334
|
-
// Standalone
|
|
335
|
-
const logger = toStructuredLogger(createConsoleLogger(), { service: 'Recovery' });
|
|
336
|
-
|
|
337
|
-
// Versori
|
|
338
|
-
const { log: logger } = ctx;
|
|
339
|
-
|
|
340
|
-
const recovery = new PartialBatchRecovery(logger);
|
|
341
|
-
const client = await createClient({ config });
|
|
342
|
-
|
|
343
|
-
const result = await recovery.processBatchWithRecovery(
|
|
344
|
-
inventoryRecords,
|
|
345
|
-
async (batch) => {
|
|
346
|
-
const job = await client.createJob({ name: 'Sync', retailerId: '1' });
|
|
347
|
-
return await client.sendBatch(job.id, {
|
|
348
|
-
action: 'UPSERT',
|
|
349
|
-
entityType: 'INVENTORY',
|
|
350
|
-
entities: batch
|
|
351
|
-
});
|
|
352
|
-
},
|
|
353
|
-
{
|
|
354
|
-
maxRetries: 3,
|
|
355
|
-
retryOnlyFailed: true,
|
|
356
|
-
batchSize: 100
|
|
357
|
-
}
|
|
358
|
-
);
|
|
359
|
-
|
|
360
|
-
console.log(`Success: ${result.successCount}, Failed: ${result.failedCount}`);
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
**When to use:**
|
|
364
|
-
- ✅ Large batch imports where some records may fail
|
|
365
|
-
- ✅ Network errors affecting subset of records
|
|
366
|
-
- ✅ Validation failures on specific records
|
|
367
|
-
- ✅ Want to minimize reprocessing overhead
|
|
368
|
-
|
|
369
|
-
**Benefits:**
|
|
370
|
-
- ✅ Only retries failed records (not entire batch)
|
|
371
|
-
- ✅ Reduces API calls and processing time
|
|
372
|
-
- ✅ Detailed failure reporting with record-level context
|
|
373
|
-
- ✅ Configurable retry logic and backoff strategies
|
|
374
|
-
|
|
375
|
-
### GraphQLExecutionError
|
|
376
|
-
|
|
377
|
-
Thrown when GraphQL mutation/query returns errors in response.
|
|
378
|
-
|
|
379
|
-
```typescript
|
|
380
|
-
class GraphQLExecutionError extends IngestionError {
|
|
381
|
-
readonly graphqlErrors: Array<{
|
|
382
|
-
message: string;
|
|
383
|
-
locations?: Array<{ line: number; column: number }>;
|
|
384
|
-
path?: Array<string | number>;
|
|
385
|
-
extensions?: Record<string, any>;
|
|
386
|
-
}>;
|
|
387
|
-
readonly query?: string;
|
|
388
|
-
readonly variables?: Record<string, any>;
|
|
389
|
-
|
|
390
|
-
getErrorMessages(): string[];
|
|
391
|
-
isValidationError(): boolean;
|
|
392
|
-
isAuthError(): boolean;
|
|
393
|
-
}
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
**Example:**
|
|
397
|
-
|
|
398
|
-
```typescript
|
|
399
|
-
try {
|
|
400
|
-
const result = await client.graphql({ query, variables });
|
|
401
|
-
if (result.errors) {
|
|
402
|
-
throw new GraphQLExecutionError(
|
|
403
|
-
'GraphQL query failed',
|
|
404
|
-
result.errors,
|
|
405
|
-
query,
|
|
406
|
-
variables
|
|
407
|
-
);
|
|
408
|
-
}
|
|
409
|
-
} catch (error) {
|
|
410
|
-
if (error instanceof GraphQLExecutionError) {
|
|
411
|
-
console.error('GraphQL errors:', error.getErrorMessages());
|
|
412
|
-
|
|
413
|
-
if (error.isAuthError()) {
|
|
414
|
-
logger.error('Authentication failed');
|
|
415
|
-
// Don't retry
|
|
416
|
-
} else if (error.isValidationError()) {
|
|
417
|
-
logger.error('GraphQL validation failed');
|
|
418
|
-
// Don't retry - fix query/variables
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
```
|
|
423
|
-
|
|
424
|
-
**Common scenarios:**
|
|
425
|
-
- GraphQL syntax errors
|
|
426
|
-
- Field permission errors
|
|
427
|
-
- Authentication failures
|
|
428
|
-
- Schema mismatches
|
|
429
|
-
|
|
430
|
-
### DataSourceError
|
|
431
|
-
|
|
432
|
-
Thrown when S3 or SFTP data source operations fail.
|
|
433
|
-
|
|
434
|
-
```typescript
|
|
435
|
-
class DataSourceError extends FluentError {
|
|
436
|
-
readonly source?: string;
|
|
437
|
-
readonly operation?: string;
|
|
438
|
-
readonly details?: Record<string, unknown>;
|
|
439
|
-
}
|
|
440
|
-
```
|
|
441
|
-
|
|
442
|
-
**Example:**
|
|
443
|
-
|
|
444
|
-
```typescript
|
|
445
|
-
try {
|
|
446
|
-
const files = await s3.listFiles({ prefix: 'orders/' });
|
|
447
|
-
} catch (error) {
|
|
448
|
-
if (error instanceof DataSourceError) {
|
|
449
|
-
logger.error('S3 operation failed:', {
|
|
450
|
-
source: error.source, // 'S3_CSV'
|
|
451
|
-
operation: error.operation, // 'listFiles'
|
|
452
|
-
details: error.details // { bucket, statusCode, etc }
|
|
453
|
-
});
|
|
454
|
-
|
|
455
|
-
// Check if retryable (network/timeout errors)
|
|
456
|
-
if (error.details?.statusCode === 429 ||
|
|
457
|
-
error.details?.statusCode === 503) {
|
|
458
|
-
// Retry with backoff
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
```
|
|
463
|
-
|
|
464
|
-
**Common scenarios:**
|
|
465
|
-
- S3 bucket access denied
|
|
466
|
-
- SFTP connection timeout
|
|
467
|
-
- File not found
|
|
468
|
-
- Network errors
|
|
469
|
-
|
|
470
|
-
**Note:** S3DataSource and SftpDataSource have built-in retry logic, so most transient errors are handled automatically.
|
|
471
|
-
|
|
472
|
-
### PathResolutionError
|
|
473
|
-
|
|
474
|
-
Thrown when source path doesn't exist in data.
|
|
475
|
-
|
|
476
|
-
```typescript
|
|
477
|
-
class PathResolutionError extends Error {
|
|
478
|
-
readonly path: string;
|
|
479
|
-
readonly cause?: Error;
|
|
480
|
-
|
|
481
|
-
constructor(path: string, cause?: Error);
|
|
482
|
-
}
|
|
483
|
-
```
|
|
484
|
-
|
|
485
|
-
**Example:**
|
|
486
|
-
|
|
487
|
-
```typescript
|
|
488
|
-
throw new PathResolutionError(
|
|
489
|
-
'order.customer.WRONG_PATH.email',
|
|
490
|
-
new Error('Path not found')
|
|
491
|
-
);
|
|
492
|
-
```
|
|
493
|
-
|
|
494
|
-
**Note:** Does NOT extend `IngestionError` - always a permanent error.
|
|
495
|
-
|
|
496
|
-
### MappingError
|
|
497
|
-
|
|
498
|
-
Thrown when field mapping fails.
|
|
499
|
-
|
|
500
|
-
```typescript
|
|
501
|
-
class MappingError extends Error {
|
|
502
|
-
readonly field?: string;
|
|
503
|
-
readonly sourcePath?: string;
|
|
504
|
-
|
|
505
|
-
constructor(
|
|
506
|
-
message: string,
|
|
507
|
-
field?: string,
|
|
508
|
-
sourcePath?: string
|
|
509
|
-
);
|
|
510
|
-
}
|
|
511
|
-
```
|
|
512
|
-
|
|
513
|
-
**Example:**
|
|
514
|
-
|
|
515
|
-
```typescript
|
|
516
|
-
throw new MappingError(
|
|
517
|
-
"Required field 'ref' is missing or empty",
|
|
518
|
-
'ref',
|
|
519
|
-
'order.customerRef'
|
|
520
|
-
);
|
|
521
|
-
```
|
|
522
|
-
|
|
523
|
-
**Note:** Does NOT extend `IngestionError` - always a permanent error.
|
|
524
|
-
|
|
525
|
-
### ResolverError
|
|
526
|
-
|
|
527
|
-
Thrown when a custom resolver fails during field transformation.
|
|
528
|
-
|
|
529
|
-
```typescript
|
|
530
|
-
class ResolverError extends Error {
|
|
531
|
-
readonly resolverName: string;
|
|
532
|
-
readonly fieldName: string;
|
|
533
|
-
readonly fieldPath: string[];
|
|
534
|
-
readonly inputValue: unknown;
|
|
535
|
-
readonly inputValueSnippet?: string;
|
|
536
|
-
readonly originalError: Error;
|
|
537
|
-
readonly timestamp: Date;
|
|
538
|
-
|
|
539
|
-
toJSON(): Record<string, unknown>;
|
|
540
|
-
}
|
|
541
|
-
```
|
|
542
|
-
|
|
543
|
-
**Example:**
|
|
544
|
-
|
|
545
|
-
```typescript
|
|
546
|
-
// Custom resolver that can fail
|
|
547
|
-
const customResolvers = {
|
|
548
|
-
'custom.parseDate': (value: unknown) => {
|
|
549
|
-
if (typeof value !== 'string') {
|
|
550
|
-
throw new Error('Date must be a string');
|
|
551
|
-
}
|
|
552
|
-
const date = new Date(value);
|
|
553
|
-
if (isNaN(date.getTime())) {
|
|
554
|
-
throw new Error(`Invalid date format: ${value}`);
|
|
555
|
-
}
|
|
556
|
-
return date.toISOString();
|
|
557
|
-
}
|
|
558
|
-
};
|
|
559
|
-
|
|
560
|
-
try {
|
|
561
|
-
const mapper = new UniversalMapper(config, { customResolvers });
|
|
562
|
-
const result = await mapper.map(data);
|
|
563
|
-
} catch (error) {
|
|
564
|
-
if (error instanceof ResolverError) {
|
|
565
|
-
logger.error('Resolver transformation failed:', {
|
|
566
|
-
resolver: error.resolverName, // 'custom.parseDate'
|
|
567
|
-
field: error.fieldName, // 'orderDate'
|
|
568
|
-
fieldPath: error.fieldPath, // ['order', 'date']
|
|
569
|
-
inputValue: error.inputValueSnippet, // 'invalid-date-string'
|
|
570
|
-
originalError: error.originalError.message,
|
|
571
|
-
timestamp: error.timestamp
|
|
572
|
-
});
|
|
573
|
-
|
|
574
|
-
// Don't retry - fix resolver logic or input data
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
```
|
|
578
|
-
|
|
579
|
-
**Common scenarios:**
|
|
580
|
-
- Date parsing failures in custom resolvers
|
|
581
|
-
- Type conversion errors
|
|
582
|
-
- Custom validation logic failures
|
|
583
|
-
- Transformation exceptions
|
|
584
|
-
|
|
585
|
-
**Note:** Does NOT extend `IngestionError` - always a permanent error indicating resolver implementation or data issues.
|
|
586
|
-
|
|
587
|
-
## Error Code Reference
|
|
588
|
-
|
|
589
|
-
### Complete Error Code Enum
|
|
590
|
-
|
|
591
|
-
```typescript
|
|
592
|
-
export enum IngestionErrorCode {
|
|
593
|
-
// File Discovery (20xx)
|
|
594
|
-
FILE_DISCOVERY_FAILED = 'FILE_DISCOVERY_FAILED',
|
|
595
|
-
FILE_ACCESS_DENIED = 'FILE_ACCESS_DENIED',
|
|
596
|
-
FILE_NOT_FOUND = 'FILE_NOT_FOUND',
|
|
597
|
-
INVALID_FILE_FORMAT = 'INVALID_FILE_FORMAT',
|
|
598
|
-
|
|
599
|
-
// Parsing (21xx)
|
|
600
|
-
PARSE_ERROR = 'PARSE_ERROR',
|
|
601
|
-
INVALID_CSV_FORMAT = 'INVALID_CSV_FORMAT',
|
|
602
|
-
INVALID_PARQUET_FORMAT = 'INVALID_PARQUET_FORMAT',
|
|
603
|
-
ENCODING_ERROR = 'ENCODING_ERROR',
|
|
604
|
-
|
|
605
|
-
// Transformation (22xx)
|
|
606
|
-
TRANSFORMATION_ERROR = 'TRANSFORMATION_ERROR',
|
|
607
|
-
FIELD_MAPPING_ERROR = 'FIELD_MAPPING_ERROR',
|
|
608
|
-
VALIDATION_ERROR = 'VALIDATION_ERROR',
|
|
609
|
-
REQUIRED_FIELD_MISSING = 'REQUIRED_FIELD_MISSING',
|
|
610
|
-
|
|
611
|
-
// Submission (23xx)
|
|
612
|
-
BATCH_SUBMISSION_ERROR = 'BATCH_SUBMISSION_ERROR',
|
|
613
|
-
JOB_CREATION_ERROR = 'JOB_CREATION_ERROR',
|
|
614
|
-
API_ERROR = 'API_ERROR',
|
|
615
|
-
NETWORK_ERROR = 'NETWORK_ERROR',
|
|
616
|
-
|
|
617
|
-
// State Management (24xx)
|
|
618
|
-
LOCK_ACQUISITION_FAILED = 'LOCK_ACQUISITION_FAILED',
|
|
619
|
-
STATE_UPDATE_FAILED = 'STATE_UPDATE_FAILED',
|
|
620
|
-
|
|
621
|
-
// Configuration (25xx)
|
|
622
|
-
CONFIGURATION_ERROR = 'CONFIGURATION_ERROR',
|
|
623
|
-
MISSING_REQUIRED_CONFIG = 'MISSING_REQUIRED_CONFIG',
|
|
624
|
-
INVALID_CONFIGURATION = 'INVALID_CONFIGURATION',
|
|
625
|
-
|
|
626
|
-
// General (26xx)
|
|
627
|
-
UNKNOWN_ERROR = 'UNKNOWN_ERROR',
|
|
628
|
-
TIMEOUT_ERROR = 'TIMEOUT_ERROR',
|
|
629
|
-
RATE_LIMIT_ERROR = 'RATE_LIMIT_ERROR',
|
|
630
|
-
}
|
|
631
|
-
```
|
|
632
|
-
|
|
633
|
-
### Error Code Categories
|
|
634
|
-
|
|
635
|
-
| Category | Codes | Retryable |
|
|
636
|
-
|----------|-------|-----------|
|
|
637
|
-
| **File Discovery** | `FILE_DISCOVERY_FAILED`, `FILE_ACCESS_DENIED`, `FILE_NOT_FOUND`, `INVALID_FILE_FORMAT` | Depends |
|
|
638
|
-
| **Parsing** | `PARSE_ERROR`, `INVALID_CSV_FORMAT`, `INVALID_PARQUET_FORMAT`, `ENCODING_ERROR` | ❌ No |
|
|
639
|
-
| **Transformation** | `TRANSFORMATION_ERROR`, `FIELD_MAPPING_ERROR`, `VALIDATION_ERROR`, `REQUIRED_FIELD_MISSING` | ❌ No |
|
|
640
|
-
| **Submission** | `BATCH_SUBMISSION_ERROR`, `JOB_CREATION_ERROR`, `API_ERROR`, `NETWORK_ERROR` | ✅ Yes |
|
|
641
|
-
| **State** | `LOCK_ACQUISITION_FAILED` | ✅ Yes |
|
|
642
|
-
| | `STATE_UPDATE_FAILED` | ❌ No |
|
|
643
|
-
| **Configuration** | `CONFIGURATION_ERROR`, `MISSING_REQUIRED_CONFIG`, `INVALID_CONFIGURATION` | ❌ No |
|
|
644
|
-
| **General** | `UNKNOWN_ERROR`, `TIMEOUT_ERROR`, `RATE_LIMIT_ERROR` | ✅ Yes |
|
|
645
|
-
|
|
646
|
-
## UTF-8 and Special Character Handling
|
|
647
|
-
|
|
648
|
-
### Automatic BOM Removal
|
|
649
|
-
|
|
650
|
-
The SDK automatically removes UTF-8 BOM (Byte Order Mark):
|
|
651
|
-
|
|
652
|
-
```typescript
|
|
653
|
-
// XMLParserService preprocessing
|
|
654
|
-
private preprocessXML(xmlContent: string): string {
|
|
655
|
-
// Remove BOM (Byte Order Mark) if present
|
|
656
|
-
let cleaned = xmlContent.replace(/^\uFEFF/, '');
|
|
657
|
-
|
|
658
|
-
// Normalize line endings (Windows/Unix/Mac)
|
|
659
|
-
cleaned = cleaned.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
660
|
-
|
|
661
|
-
// Remove XML comments
|
|
662
|
-
cleaned = cleaned.replace(/<!--[\s\S]*?-->/g, '');
|
|
663
|
-
|
|
664
|
-
return cleaned.trim();
|
|
665
|
-
}
|
|
666
|
-
```
|
|
667
|
-
|
|
668
|
-
### Supported Encodings
|
|
669
|
-
|
|
670
|
-
- ✅ UTF-8 (standard)
|
|
671
|
-
- ✅ UTF-8 with BOM
|
|
672
|
-
- ✅ Unicode characters (emoji, Chinese, Arabic, accented characters)
|
|
673
|
-
|
|
674
|
-
### Special Character Escaping
|
|
675
|
-
|
|
676
|
-
XML special characters are automatically escaped:
|
|
677
|
-
|
|
678
|
-
```typescript
|
|
679
|
-
private escapeXML(str: string): string {
|
|
680
|
-
return str
|
|
681
|
-
.replace(/&/g, '&') // & → &
|
|
682
|
-
.replace(/</g, '<') // < → <
|
|
683
|
-
.replace(/>/g, '>') // > → >
|
|
684
|
-
.replace(/"/g, '"') // " → "
|
|
685
|
-
.replace(/'/g, '''); // ' → '
|
|
686
|
-
}
|
|
687
|
-
```
|
|
688
|
-
|
|
689
|
-
**Example:**
|
|
690
|
-
|
|
691
|
-
```xml
|
|
692
|
-
<order>
|
|
693
|
-
<customer>
|
|
694
|
-
<name>José García</name>
|
|
695
|
-
<email>josé@example.com</email>
|
|
696
|
-
<notes>Special: & < > " 中文 🎉</notes>
|
|
697
|
-
</customer>
|
|
698
|
-
</order>
|
|
699
|
-
```
|
|
700
|
-
|
|
701
|
-
## Best Practices
|
|
702
|
-
|
|
703
|
-
### Error Handling Checklist
|
|
704
|
-
|
|
705
|
-
- [ ] Wrap all SDK operations in try-catch blocks
|
|
706
|
-
- [ ] Check error types with `instanceof`
|
|
707
|
-
- [ ] Use `error.toJSON()` for structured logging
|
|
708
|
-
- [ ] Check `error.isRetryable()` before retry logic
|
|
709
|
-
- [ ] Re-throw errors after handling (don't silence)
|
|
710
|
-
- [ ] Log with correlation IDs and context
|
|
711
|
-
- [ ] Monitor error rates and patterns
|
|
712
|
-
- [ ] Alert on high error frequencies
|
|
713
|
-
- [ ] Document error scenarios for your team
|
|
714
|
-
- [ ] Test error paths in your code
|
|
715
|
-
|
|
716
|
-
### Do's and Don'ts
|
|
717
|
-
|
|
718
|
-
#### ✅ DO
|
|
719
|
-
|
|
720
|
-
```typescript
|
|
721
|
-
// ✅ Always wrap in try-catch
|
|
722
|
-
try {
|
|
723
|
-
const result = await mapper.map(data);
|
|
724
|
-
} catch (error) {
|
|
725
|
-
logger.error('Mapping failed:', error instanceof IngestionError ? error.toJSON() : error);
|
|
726
|
-
throw error;
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
// ✅ Check error types
|
|
730
|
-
if (error instanceof MappingError) {
|
|
731
|
-
logger.error('Mapping error:', { field: error.field, path: error.sourcePath });
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
// ✅ Use isRetryable()
|
|
735
|
-
if (error instanceof IngestionError && error.isRetryable()) {
|
|
736
|
-
return scheduleRetry();
|
|
737
|
-
}
|
|
738
|
-
|
|
739
|
-
// ✅ Log with context
|
|
740
|
-
logger.error('Processing failed', {
|
|
741
|
-
error: error.toJSON(),
|
|
742
|
-
orderId,
|
|
743
|
-
fileName,
|
|
744
|
-
correlationId
|
|
745
|
-
});
|
|
746
|
-
```
|
|
747
|
-
|
|
748
|
-
#### ❌ DON'T
|
|
749
|
-
|
|
750
|
-
```typescript
|
|
751
|
-
// ❌ Don't silence errors
|
|
752
|
-
try {
|
|
753
|
-
await processOrder(data);
|
|
754
|
-
} catch (error) {
|
|
755
|
-
// Do nothing - ERROR IS LOST!
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
// ❌ Don't retry permanent errors
|
|
759
|
-
if (error instanceof FileParsingError) {
|
|
760
|
-
await retryOperation(); // Won't succeed!
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
// ❌ Don't log without context
|
|
764
|
-
logger.error('Error occurred');
|
|
765
|
-
|
|
766
|
-
// ❌ Don't throw strings
|
|
767
|
-
throw 'Something went wrong'; // Use Error objects!
|
|
768
|
-
```
|
|
769
|
-
|
|
770
|
-
### Error Context Best Practices
|
|
771
|
-
|
|
772
|
-
Always include these in error logs:
|
|
773
|
-
|
|
774
|
-
1. **Timestamp** - When error occurred
|
|
775
|
-
2. **Correlation ID** - Track across systems
|
|
776
|
-
3. **Business context** - Order ID, customer ID, etc.
|
|
777
|
-
4. **Operation** - What was being attempted
|
|
778
|
-
5. **Attempt** - Retry attempt number
|
|
779
|
-
6. **Environment** - Dev, staging, production
|
|
780
|
-
7. **Version** - Application version
|
|
781
|
-
|
|
782
|
-
```typescript
|
|
783
|
-
logger.error('Order processing failed', {
|
|
784
|
-
timestamp: new Date().toISOString(),
|
|
785
|
-
correlationId: context.correlationId,
|
|
786
|
-
orderId: metadata.orderId,
|
|
787
|
-
customerId: metadata.customerId,
|
|
788
|
-
operation: 'processOrder',
|
|
789
|
-
attempt: retryAttempt,
|
|
790
|
-
environment: process.env.NODE_ENV,
|
|
791
|
-
version: process.env.APP_VERSION,
|
|
792
|
-
error: error instanceof IngestionError ? error.toJSON() : error.message
|
|
793
|
-
});
|
|
794
|
-
```
|
|
795
|
-
|
|
796
|
-
## Summary
|
|
797
|
-
|
|
798
|
-
### Key Concepts
|
|
799
|
-
|
|
800
|
-
1. **Fail-Fast** - One error stops everything, no partial data
|
|
801
|
-
2. **Error Hierarchy** - All ingestion errors extend `IngestionError`
|
|
802
|
-
3. **Error Codes** - Machine-readable codes for programmatic handling
|
|
803
|
-
4. **Retryability** - Use `isRetryable()` to determine retry strategy
|
|
804
|
-
5. **Structured Logging** - Use `toJSON()` for complete error data
|
|
805
|
-
6. **UTF-8 Support** - Automatic BOM removal and special character handling
|
|
806
|
-
|
|
807
|
-
### Quick Reference Table
|
|
808
|
-
|
|
809
|
-
| Error Class | When Thrown | Retryable | Key Properties |
|
|
810
|
-
|-------------|-------------|-----------|----------------|
|
|
811
|
-
| `FileParsingError` | XML/CSV/JSON parsing fails | ❌ No | `fileName`, `lineNumber` |
|
|
812
|
-
| `PathResolutionError` | Path doesn't exist in data | ❌ No | `path` |
|
|
813
|
-
| `MappingError` | Field mapping fails | ❌ No | `field`, `sourcePath` |
|
|
814
|
-
| `ResolverError` | Resolver transformation fails | ❌ No | `resolverName`, `fieldName`, `fieldPath`, `originalError` |
|
|
815
|
-
| `ValidationError` | Data validation fails | ❌ No | `validationErrors[]` |
|
|
816
|
-
| `ConfigurationError` | Invalid config | ❌ No | `configKey` |
|
|
817
|
-
| `FluentAPIError` | HTTP error (4xx/5xx) | ✅ Yes (5xx) | `statusCode`, `details` |
|
|
818
|
-
| `AuthenticationError` | Auth failed (after retries) | ❌ No | `statusCode` (401) |
|
|
819
|
-
| `BatchSubmissionError` | API submission fails | ✅ Yes | `jobId`, `batchId` |
|
|
820
|
-
| `GraphQLExecutionError` | GraphQL errors in response | ❌ No* | `graphqlErrors[]`, `query`, `variables` |
|
|
821
|
-
| `DataSourceError` | S3/SFTP operation fails | Depends† | `source`, `operation`, `details` |
|
|
822
|
-
| `IngestionError` (base) | Various ingestion issues | Depends | `code`, `context` |
|
|
823
|
-
|
|
824
|
-
**Notes:**
|
|
825
|
-
- *GraphQLExecutionError: Not retryable unless due to network issues (check extensions)
|
|
826
|
-
- †DataSourceError: Retryable if network/timeout error; S3/SFTP have built-in retry (v0.1.10+)
|
|
827
|
-
|
|
828
|
-
### Related Documentation
|
|
829
|
-
|
|
830
|
-
- [Module 1: Foundations](./error-handling-01-foundations.md) - Fail-fast principles
|
|
831
|
-
- [Module 2: Error Types](./error-handling-02-error-types.md) - Error class hierarchy
|
|
832
|
-
- [Module 3: UTF-8 Handling](./error-handling-03-utf8-handling.md) - UTF-8 encoding
|
|
833
|
-
- [Module 4: Error Scenarios](./error-handling-04-error-scenarios.md) - Real-world examples
|
|
834
|
-
- [Module 5: Calling Patterns](./error-handling-05-calling-patterns.md) - Code patterns
|
|
835
|
-
- [Module 6: Retry Strategies](./error-handling-06-retry-strategies.md) - Retry logic
|
|
836
|
-
- [Module 7: Monitoring](./error-handling-07-monitoring.md) - Logging best practices
|
|
837
|
-
|
|
838
|
-
## Need Help?
|
|
839
|
-
|
|
840
|
-
- 📖 Browse [Examples](../examples/)
|
|
841
|
-
- 🔍 Check [Error Scenarios](./error-handling-04-error-scenarios.md)
|
|
842
|
-
- 📋 Review [Quick Reference](../../../02-CORE-GUIDES/advanced-services/advanced-services-quick-reference.md)
|
|
843
|
-
- 🐛 Report issues at [GitHub](https://github.com/fluentcommerce/fc-connect-sdk/issues)
|
|
844
|
-
|
|
845
|
-
---
|
|
846
|
-
|
|
847
|
-
**Previous:** [← Module 7: Monitoring](./error-handling-07-monitoring.md)
|
|
1
|
+
# Module 8: API Reference
|
|
2
|
+
|
|
3
|
+
**Level:** Reference
|
|
4
|
+
**Estimated Time:** As needed
|
|
5
|
+
|
|
6
|
+
## Overview
|
|
7
|
+
|
|
8
|
+
This module provides complete API documentation for all error classes, error codes, and best practices for error handling in the SDK.
|
|
9
|
+
|
|
10
|
+
## Error Class Reference
|
|
11
|
+
|
|
12
|
+
### IngestionError (Base Class)
|
|
13
|
+
|
|
14
|
+
Base class for all ingestion-related errors.
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
abstract class IngestionError extends Error {
|
|
18
|
+
readonly code: IngestionErrorCode;
|
|
19
|
+
readonly context?: Record<string, any>;
|
|
20
|
+
readonly timestamp: Date;
|
|
21
|
+
readonly correlationId?: string;
|
|
22
|
+
|
|
23
|
+
constructor(
|
|
24
|
+
message: string,
|
|
25
|
+
code: IngestionErrorCode,
|
|
26
|
+
context?: Record<string, any>,
|
|
27
|
+
correlationId?: string
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
toJSON(): Record<string, any>;
|
|
31
|
+
isRetryable(): boolean;
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Properties:**
|
|
36
|
+
- `code`: Machine-readable error code from `IngestionErrorCode` enum
|
|
37
|
+
- `context`: Additional error context (file name, record index, etc.)
|
|
38
|
+
- `timestamp`: When the error occurred
|
|
39
|
+
- `correlationId`: For tracking errors across distributed systems
|
|
40
|
+
- `message`: Human-readable error description
|
|
41
|
+
- `name`: Error class name
|
|
42
|
+
- `stack`: Stack trace
|
|
43
|
+
|
|
44
|
+
**Methods:**
|
|
45
|
+
|
|
46
|
+
#### toJSON()
|
|
47
|
+
|
|
48
|
+
Serializes error to JSON for logging:
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
const error = new FileParsingError('Invalid XML', 'order.xml', 42);
|
|
52
|
+
const json = error.toJSON();
|
|
53
|
+
// {
|
|
54
|
+
// name: 'FileParsingError',
|
|
55
|
+
// message: 'Invalid XML',
|
|
56
|
+
// code: 'PARSE_ERROR',
|
|
57
|
+
// fileName: 'order.xml',
|
|
58
|
+
// lineNumber: 42,
|
|
59
|
+
// timestamp: '2025-01-10T12:34:56.789Z',
|
|
60
|
+
// stack: '...'
|
|
61
|
+
// }
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
#### isRetryable()
|
|
65
|
+
|
|
66
|
+
Determines if error should be retried:
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
if (error.isRetryable()) {
|
|
70
|
+
// Retry with exponential backoff
|
|
71
|
+
await retryOperation();
|
|
72
|
+
} else {
|
|
73
|
+
// Permanent failure - don't retry
|
|
74
|
+
throw error;
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Retryable codes:**
|
|
79
|
+
- `NETWORK_ERROR`
|
|
80
|
+
- `TIMEOUT_ERROR`
|
|
81
|
+
- `RATE_LIMIT_ERROR`
|
|
82
|
+
- `LOCK_ACQUISITION_FAILED`
|
|
83
|
+
|
|
84
|
+
### FileDiscoveryError
|
|
85
|
+
|
|
86
|
+
Thrown when file discovery or access fails.
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
class FileDiscoveryError extends IngestionError {
|
|
90
|
+
readonly fileName?: string;
|
|
91
|
+
readonly path?: string;
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Example:**
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
throw new FileDiscoveryError(
|
|
99
|
+
'Failed to list S3 bucket',
|
|
100
|
+
IngestionErrorCode.FILE_DISCOVERY_FAILED,
|
|
101
|
+
{ bucket: 's3://my-bucket', prefix: 'orders/' }
|
|
102
|
+
);
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### FileParsingError
|
|
106
|
+
|
|
107
|
+
Thrown when file parsing fails.
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
class FileParsingError extends IngestionError {
|
|
111
|
+
readonly fileName?: string;
|
|
112
|
+
readonly lineNumber?: number;
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**Example:**
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
throw new FileParsingError(
|
|
120
|
+
'Unclosed XML tag',
|
|
121
|
+
'order-123.xml',
|
|
122
|
+
42, // line number
|
|
123
|
+
{ tag: 'customer', position: 1234 }
|
|
124
|
+
);
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Common scenarios:**
|
|
128
|
+
- Invalid XML syntax
|
|
129
|
+
- Malformed JSON
|
|
130
|
+
- CSV column mismatch
|
|
131
|
+
- Corrupted Parquet file
|
|
132
|
+
|
|
133
|
+
### TransformationError
|
|
134
|
+
|
|
135
|
+
Thrown during data transformation.
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
class TransformationError extends IngestionError {
|
|
139
|
+
readonly recordIndex?: number;
|
|
140
|
+
readonly fieldName?: string;
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Example:**
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
throw new TransformationError(
|
|
148
|
+
'Failed to parse date',
|
|
149
|
+
IngestionErrorCode.TRANSFORMATION_ERROR,
|
|
150
|
+
{
|
|
151
|
+
recordIndex: 5,
|
|
152
|
+
fieldName: 'orderDate',
|
|
153
|
+
value: 'invalid-date'
|
|
154
|
+
}
|
|
155
|
+
);
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### BatchSubmissionError
|
|
159
|
+
|
|
160
|
+
Thrown when Batch API submission fails.
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
class BatchSubmissionError extends IngestionError {
|
|
164
|
+
readonly jobId?: string;
|
|
165
|
+
readonly batchId?: string;
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Example:**
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
throw new BatchSubmissionError(
|
|
173
|
+
'Batch submission failed',
|
|
174
|
+
IngestionErrorCode.BATCH_SUBMISSION_ERROR,
|
|
175
|
+
{
|
|
176
|
+
jobId: 'JOB-123',
|
|
177
|
+
batchId: 'BATCH-456',
|
|
178
|
+
statusCode: 500
|
|
179
|
+
}
|
|
180
|
+
);
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### ConfigurationError
|
|
184
|
+
|
|
185
|
+
Thrown when SDK configuration is invalid.
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
class ConfigurationError extends IngestionError {
|
|
189
|
+
readonly configKey?: string;
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**Example:**
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
throw new ConfigurationError(
|
|
197
|
+
'Missing required configuration',
|
|
198
|
+
IngestionErrorCode.MISSING_REQUIRED_CONFIG,
|
|
199
|
+
{ configKey: 'FLUENT_CLIENT_ID' }
|
|
200
|
+
);
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### ValidationError
|
|
204
|
+
|
|
205
|
+
Thrown when data validation fails.
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
class ValidationError extends IngestionError {
|
|
209
|
+
readonly validationErrors: Array<{
|
|
210
|
+
field?: string;
|
|
211
|
+
value?: any;
|
|
212
|
+
rule?: string;
|
|
213
|
+
message: string;
|
|
214
|
+
}>;
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**Example:**
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
throw new ValidationError(
|
|
222
|
+
'Validation failed',
|
|
223
|
+
[
|
|
224
|
+
{
|
|
225
|
+
field: 'email',
|
|
226
|
+
value: 'invalid-email',
|
|
227
|
+
rule: 'email_format',
|
|
228
|
+
message: 'Invalid email format'
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
field: 'quantity',
|
|
232
|
+
value: -5,
|
|
233
|
+
rule: 'min_value',
|
|
234
|
+
message: 'Quantity must be positive'
|
|
235
|
+
}
|
|
236
|
+
]
|
|
237
|
+
);
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### AggregateIngestionError
|
|
241
|
+
|
|
242
|
+
Thrown when multiple errors occur during batch processing.
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
class AggregateIngestionError extends IngestionError {
|
|
246
|
+
readonly errors: IngestionError[];
|
|
247
|
+
|
|
248
|
+
getAllCodes(): IngestionErrorCode[];
|
|
249
|
+
hasRetryableError(): boolean;
|
|
250
|
+
getErrorsByCode(code: IngestionErrorCode): IngestionError[];
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
**Example:**
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
const errors = [
|
|
258
|
+
new FileParsingError('Invalid XML', 'order-1.xml', 10),
|
|
259
|
+
new FileParsingError('Invalid XML', 'order-2.xml', 20)
|
|
260
|
+
];
|
|
261
|
+
|
|
262
|
+
throw new AggregateIngestionError(
|
|
263
|
+
`${errors.length} files failed processing`,
|
|
264
|
+
errors,
|
|
265
|
+
{ batchId: 'BATCH-123' }
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
// Check if any errors are retryable
|
|
269
|
+
if (aggregateError.hasRetryableError()) {
|
|
270
|
+
// Retry the batch
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## New Services for Error Recovery
|
|
275
|
+
|
|
276
|
+
### PartialBatchRecovery
|
|
277
|
+
|
|
278
|
+
Service for handling partial batch failures with automatic recovery.
|
|
279
|
+
|
|
280
|
+
**Purpose:** Retry only failed records instead of entire batches, reducing overhead and improving efficiency.
|
|
281
|
+
|
|
282
|
+
```typescript
|
|
283
|
+
class PartialBatchRecovery {
|
|
284
|
+
constructor(logger: Logger);
|
|
285
|
+
|
|
286
|
+
async processBatchWithRecovery<T>(
|
|
287
|
+
records: T[],
|
|
288
|
+
processFn: (batch: T[]) => Promise<any>,
|
|
289
|
+
options?: RecoveryOptions
|
|
290
|
+
): Promise<RecoveryResult>;
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
**Options:**
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
interface RecoveryOptions {
|
|
298
|
+
maxRetries?: number; // Max retry attempts per record (default: 3)
|
|
299
|
+
retryOnlyFailed?: boolean; // Only retry failed records (default: true)
|
|
300
|
+
batchSize?: number; // Batch size for processing (default: 100)
|
|
301
|
+
retryDelay?: number; // Delay between retries in ms (default: 1000)
|
|
302
|
+
exponentialBackoff?: boolean; // Use exponential backoff (default: true)
|
|
303
|
+
shouldRetry?: (error: Error, attempt: number) => boolean;
|
|
304
|
+
calculateDelay?: (attempt: number, baseDelay: number) => number;
|
|
305
|
+
onProgress?: (current: number, total: number) => void;
|
|
306
|
+
onRetry?: (record: any, attempt: number, error: Error) => void;
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
**Return Value:**
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
interface RecoveryResult {
|
|
314
|
+
successCount: number;
|
|
315
|
+
failedCount: number;
|
|
316
|
+
failedRecords: Array<{
|
|
317
|
+
record: any;
|
|
318
|
+
error: Error;
|
|
319
|
+
attemptCount: number;
|
|
320
|
+
}>;
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
**Example:**
|
|
325
|
+
|
|
326
|
+
```typescript
|
|
327
|
+
import {
|
|
328
|
+
PartialBatchRecovery,
|
|
329
|
+
createClient,
|
|
330
|
+
createConsoleLogger,
|
|
331
|
+
toStructuredLogger
|
|
332
|
+
} from '@fluentcommerce/fc-connect-sdk';
|
|
333
|
+
|
|
334
|
+
// Standalone
|
|
335
|
+
const logger = toStructuredLogger(createConsoleLogger(), { service: 'Recovery' });
|
|
336
|
+
|
|
337
|
+
// Versori
|
|
338
|
+
const { log: logger } = ctx;
|
|
339
|
+
|
|
340
|
+
const recovery = new PartialBatchRecovery(logger);
|
|
341
|
+
const client = await createClient({ config });
|
|
342
|
+
|
|
343
|
+
const result = await recovery.processBatchWithRecovery(
|
|
344
|
+
inventoryRecords,
|
|
345
|
+
async (batch) => {
|
|
346
|
+
const job = await client.createJob({ name: 'Sync', retailerId: '1' });
|
|
347
|
+
return await client.sendBatch(job.id, {
|
|
348
|
+
action: 'UPSERT',
|
|
349
|
+
entityType: 'INVENTORY',
|
|
350
|
+
entities: batch
|
|
351
|
+
});
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
maxRetries: 3,
|
|
355
|
+
retryOnlyFailed: true,
|
|
356
|
+
batchSize: 100
|
|
357
|
+
}
|
|
358
|
+
);
|
|
359
|
+
|
|
360
|
+
console.log(`Success: ${result.successCount}, Failed: ${result.failedCount}`);
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
**When to use:**
|
|
364
|
+
- ✅ Large batch imports where some records may fail
|
|
365
|
+
- ✅ Network errors affecting subset of records
|
|
366
|
+
- ✅ Validation failures on specific records
|
|
367
|
+
- ✅ Want to minimize reprocessing overhead
|
|
368
|
+
|
|
369
|
+
**Benefits:**
|
|
370
|
+
- ✅ Only retries failed records (not entire batch)
|
|
371
|
+
- ✅ Reduces API calls and processing time
|
|
372
|
+
- ✅ Detailed failure reporting with record-level context
|
|
373
|
+
- ✅ Configurable retry logic and backoff strategies
|
|
374
|
+
|
|
375
|
+
### GraphQLExecutionError
|
|
376
|
+
|
|
377
|
+
Thrown when GraphQL mutation/query returns errors in response.
|
|
378
|
+
|
|
379
|
+
```typescript
|
|
380
|
+
class GraphQLExecutionError extends IngestionError {
|
|
381
|
+
readonly graphqlErrors: Array<{
|
|
382
|
+
message: string;
|
|
383
|
+
locations?: Array<{ line: number; column: number }>;
|
|
384
|
+
path?: Array<string | number>;
|
|
385
|
+
extensions?: Record<string, any>;
|
|
386
|
+
}>;
|
|
387
|
+
readonly query?: string;
|
|
388
|
+
readonly variables?: Record<string, any>;
|
|
389
|
+
|
|
390
|
+
getErrorMessages(): string[];
|
|
391
|
+
isValidationError(): boolean;
|
|
392
|
+
isAuthError(): boolean;
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
**Example:**
|
|
397
|
+
|
|
398
|
+
```typescript
|
|
399
|
+
try {
|
|
400
|
+
const result = await client.graphql({ query, variables });
|
|
401
|
+
if (result.errors) {
|
|
402
|
+
throw new GraphQLExecutionError(
|
|
403
|
+
'GraphQL query failed',
|
|
404
|
+
result.errors,
|
|
405
|
+
query,
|
|
406
|
+
variables
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
} catch (error) {
|
|
410
|
+
if (error instanceof GraphQLExecutionError) {
|
|
411
|
+
console.error('GraphQL errors:', error.getErrorMessages());
|
|
412
|
+
|
|
413
|
+
if (error.isAuthError()) {
|
|
414
|
+
logger.error('Authentication failed');
|
|
415
|
+
// Don't retry
|
|
416
|
+
} else if (error.isValidationError()) {
|
|
417
|
+
logger.error('GraphQL validation failed');
|
|
418
|
+
// Don't retry - fix query/variables
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
**Common scenarios:**
|
|
425
|
+
- GraphQL syntax errors
|
|
426
|
+
- Field permission errors
|
|
427
|
+
- Authentication failures
|
|
428
|
+
- Schema mismatches
|
|
429
|
+
|
|
430
|
+
### DataSourceError
|
|
431
|
+
|
|
432
|
+
Thrown when S3 or SFTP data source operations fail.
|
|
433
|
+
|
|
434
|
+
```typescript
|
|
435
|
+
class DataSourceError extends FluentError {
|
|
436
|
+
readonly source?: string;
|
|
437
|
+
readonly operation?: string;
|
|
438
|
+
readonly details?: Record<string, unknown>;
|
|
439
|
+
}
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
**Example:**
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
try {
|
|
446
|
+
const files = await s3.listFiles({ prefix: 'orders/' });
|
|
447
|
+
} catch (error) {
|
|
448
|
+
if (error instanceof DataSourceError) {
|
|
449
|
+
logger.error('S3 operation failed:', {
|
|
450
|
+
source: error.source, // 'S3_CSV'
|
|
451
|
+
operation: error.operation, // 'listFiles'
|
|
452
|
+
details: error.details // { bucket, statusCode, etc }
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
// Check if retryable (network/timeout errors)
|
|
456
|
+
if (error.details?.statusCode === 429 ||
|
|
457
|
+
error.details?.statusCode === 503) {
|
|
458
|
+
// Retry with backoff
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
**Common scenarios:**
|
|
465
|
+
- S3 bucket access denied
|
|
466
|
+
- SFTP connection timeout
|
|
467
|
+
- File not found
|
|
468
|
+
- Network errors
|
|
469
|
+
|
|
470
|
+
**Note:** S3DataSource and SftpDataSource have built-in retry logic, so most transient errors are handled automatically.
|
|
471
|
+
|
|
472
|
+
### PathResolutionError
|
|
473
|
+
|
|
474
|
+
Thrown when source path doesn't exist in data.
|
|
475
|
+
|
|
476
|
+
```typescript
|
|
477
|
+
class PathResolutionError extends Error {
|
|
478
|
+
readonly path: string;
|
|
479
|
+
readonly cause?: Error;
|
|
480
|
+
|
|
481
|
+
constructor(path: string, cause?: Error);
|
|
482
|
+
}
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
**Example:**
|
|
486
|
+
|
|
487
|
+
```typescript
|
|
488
|
+
throw new PathResolutionError(
|
|
489
|
+
'order.customer.WRONG_PATH.email',
|
|
490
|
+
new Error('Path not found')
|
|
491
|
+
);
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
**Note:** Does NOT extend `IngestionError` - always a permanent error.
|
|
495
|
+
|
|
496
|
+
### MappingError
|
|
497
|
+
|
|
498
|
+
Thrown when field mapping fails.
|
|
499
|
+
|
|
500
|
+
```typescript
|
|
501
|
+
class MappingError extends Error {
|
|
502
|
+
readonly field?: string;
|
|
503
|
+
readonly sourcePath?: string;
|
|
504
|
+
|
|
505
|
+
constructor(
|
|
506
|
+
message: string,
|
|
507
|
+
field?: string,
|
|
508
|
+
sourcePath?: string
|
|
509
|
+
);
|
|
510
|
+
}
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
**Example:**
|
|
514
|
+
|
|
515
|
+
```typescript
|
|
516
|
+
throw new MappingError(
|
|
517
|
+
"Required field 'ref' is missing or empty",
|
|
518
|
+
'ref',
|
|
519
|
+
'order.customerRef'
|
|
520
|
+
);
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
**Note:** Does NOT extend `IngestionError` - always a permanent error.
|
|
524
|
+
|
|
525
|
+
### ResolverError
|
|
526
|
+
|
|
527
|
+
Thrown when a custom resolver fails during field transformation.
|
|
528
|
+
|
|
529
|
+
```typescript
|
|
530
|
+
class ResolverError extends Error {
|
|
531
|
+
readonly resolverName: string;
|
|
532
|
+
readonly fieldName: string;
|
|
533
|
+
readonly fieldPath: string[];
|
|
534
|
+
readonly inputValue: unknown;
|
|
535
|
+
readonly inputValueSnippet?: string;
|
|
536
|
+
readonly originalError: Error;
|
|
537
|
+
readonly timestamp: Date;
|
|
538
|
+
|
|
539
|
+
toJSON(): Record<string, unknown>;
|
|
540
|
+
}
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
**Example:**
|
|
544
|
+
|
|
545
|
+
```typescript
|
|
546
|
+
// Custom resolver that can fail
|
|
547
|
+
const customResolvers = {
|
|
548
|
+
'custom.parseDate': (value: unknown) => {
|
|
549
|
+
if (typeof value !== 'string') {
|
|
550
|
+
throw new Error('Date must be a string');
|
|
551
|
+
}
|
|
552
|
+
const date = new Date(value);
|
|
553
|
+
if (isNaN(date.getTime())) {
|
|
554
|
+
throw new Error(`Invalid date format: ${value}`);
|
|
555
|
+
}
|
|
556
|
+
return date.toISOString();
|
|
557
|
+
}
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
try {
|
|
561
|
+
const mapper = new UniversalMapper(config, { customResolvers });
|
|
562
|
+
const result = await mapper.map(data);
|
|
563
|
+
} catch (error) {
|
|
564
|
+
if (error instanceof ResolverError) {
|
|
565
|
+
logger.error('Resolver transformation failed:', {
|
|
566
|
+
resolver: error.resolverName, // 'custom.parseDate'
|
|
567
|
+
field: error.fieldName, // 'orderDate'
|
|
568
|
+
fieldPath: error.fieldPath, // ['order', 'date']
|
|
569
|
+
inputValue: error.inputValueSnippet, // 'invalid-date-string'
|
|
570
|
+
originalError: error.originalError.message,
|
|
571
|
+
timestamp: error.timestamp
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
// Don't retry - fix resolver logic or input data
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
**Common scenarios:**
|
|
580
|
+
- Date parsing failures in custom resolvers
|
|
581
|
+
- Type conversion errors
|
|
582
|
+
- Custom validation logic failures
|
|
583
|
+
- Transformation exceptions
|
|
584
|
+
|
|
585
|
+
**Note:** Does NOT extend `IngestionError` - always a permanent error indicating resolver implementation or data issues.
|
|
586
|
+
|
|
587
|
+
## Error Code Reference
|
|
588
|
+
|
|
589
|
+
### Complete Error Code Enum
|
|
590
|
+
|
|
591
|
+
```typescript
|
|
592
|
+
export enum IngestionErrorCode {
|
|
593
|
+
// File Discovery (20xx)
|
|
594
|
+
FILE_DISCOVERY_FAILED = 'FILE_DISCOVERY_FAILED',
|
|
595
|
+
FILE_ACCESS_DENIED = 'FILE_ACCESS_DENIED',
|
|
596
|
+
FILE_NOT_FOUND = 'FILE_NOT_FOUND',
|
|
597
|
+
INVALID_FILE_FORMAT = 'INVALID_FILE_FORMAT',
|
|
598
|
+
|
|
599
|
+
// Parsing (21xx)
|
|
600
|
+
PARSE_ERROR = 'PARSE_ERROR',
|
|
601
|
+
INVALID_CSV_FORMAT = 'INVALID_CSV_FORMAT',
|
|
602
|
+
INVALID_PARQUET_FORMAT = 'INVALID_PARQUET_FORMAT',
|
|
603
|
+
ENCODING_ERROR = 'ENCODING_ERROR',
|
|
604
|
+
|
|
605
|
+
// Transformation (22xx)
|
|
606
|
+
TRANSFORMATION_ERROR = 'TRANSFORMATION_ERROR',
|
|
607
|
+
FIELD_MAPPING_ERROR = 'FIELD_MAPPING_ERROR',
|
|
608
|
+
VALIDATION_ERROR = 'VALIDATION_ERROR',
|
|
609
|
+
REQUIRED_FIELD_MISSING = 'REQUIRED_FIELD_MISSING',
|
|
610
|
+
|
|
611
|
+
// Submission (23xx)
|
|
612
|
+
BATCH_SUBMISSION_ERROR = 'BATCH_SUBMISSION_ERROR',
|
|
613
|
+
JOB_CREATION_ERROR = 'JOB_CREATION_ERROR',
|
|
614
|
+
API_ERROR = 'API_ERROR',
|
|
615
|
+
NETWORK_ERROR = 'NETWORK_ERROR',
|
|
616
|
+
|
|
617
|
+
// State Management (24xx)
|
|
618
|
+
LOCK_ACQUISITION_FAILED = 'LOCK_ACQUISITION_FAILED',
|
|
619
|
+
STATE_UPDATE_FAILED = 'STATE_UPDATE_FAILED',
|
|
620
|
+
|
|
621
|
+
// Configuration (25xx)
|
|
622
|
+
CONFIGURATION_ERROR = 'CONFIGURATION_ERROR',
|
|
623
|
+
MISSING_REQUIRED_CONFIG = 'MISSING_REQUIRED_CONFIG',
|
|
624
|
+
INVALID_CONFIGURATION = 'INVALID_CONFIGURATION',
|
|
625
|
+
|
|
626
|
+
// General (26xx)
|
|
627
|
+
UNKNOWN_ERROR = 'UNKNOWN_ERROR',
|
|
628
|
+
TIMEOUT_ERROR = 'TIMEOUT_ERROR',
|
|
629
|
+
RATE_LIMIT_ERROR = 'RATE_LIMIT_ERROR',
|
|
630
|
+
}
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
### Error Code Categories
|
|
634
|
+
|
|
635
|
+
| Category | Codes | Retryable |
|
|
636
|
+
|----------|-------|-----------|
|
|
637
|
+
| **File Discovery** | `FILE_DISCOVERY_FAILED`, `FILE_ACCESS_DENIED`, `FILE_NOT_FOUND`, `INVALID_FILE_FORMAT` | Depends |
|
|
638
|
+
| **Parsing** | `PARSE_ERROR`, `INVALID_CSV_FORMAT`, `INVALID_PARQUET_FORMAT`, `ENCODING_ERROR` | ❌ No |
|
|
639
|
+
| **Transformation** | `TRANSFORMATION_ERROR`, `FIELD_MAPPING_ERROR`, `VALIDATION_ERROR`, `REQUIRED_FIELD_MISSING` | ❌ No |
|
|
640
|
+
| **Submission** | `BATCH_SUBMISSION_ERROR`, `JOB_CREATION_ERROR`, `API_ERROR`, `NETWORK_ERROR` | ✅ Yes |
|
|
641
|
+
| **State** | `LOCK_ACQUISITION_FAILED` | ✅ Yes |
|
|
642
|
+
| | `STATE_UPDATE_FAILED` | ❌ No |
|
|
643
|
+
| **Configuration** | `CONFIGURATION_ERROR`, `MISSING_REQUIRED_CONFIG`, `INVALID_CONFIGURATION` | ❌ No |
|
|
644
|
+
| **General** | `UNKNOWN_ERROR`, `TIMEOUT_ERROR`, `RATE_LIMIT_ERROR` | ✅ Yes |
|
|
645
|
+
|
|
646
|
+
## UTF-8 and Special Character Handling
|
|
647
|
+
|
|
648
|
+
### Automatic BOM Removal
|
|
649
|
+
|
|
650
|
+
The SDK automatically removes UTF-8 BOM (Byte Order Mark):
|
|
651
|
+
|
|
652
|
+
```typescript
|
|
653
|
+
// XMLParserService preprocessing
|
|
654
|
+
private preprocessXML(xmlContent: string): string {
|
|
655
|
+
// Remove BOM (Byte Order Mark) if present
|
|
656
|
+
let cleaned = xmlContent.replace(/^\uFEFF/, '');
|
|
657
|
+
|
|
658
|
+
// Normalize line endings (Windows/Unix/Mac)
|
|
659
|
+
cleaned = cleaned.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
660
|
+
|
|
661
|
+
// Remove XML comments
|
|
662
|
+
cleaned = cleaned.replace(/<!--[\s\S]*?-->/g, '');
|
|
663
|
+
|
|
664
|
+
return cleaned.trim();
|
|
665
|
+
}
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
### Supported Encodings
|
|
669
|
+
|
|
670
|
+
- ✅ UTF-8 (standard)
|
|
671
|
+
- ✅ UTF-8 with BOM
|
|
672
|
+
- ✅ Unicode characters (emoji, Chinese, Arabic, accented characters)
|
|
673
|
+
|
|
674
|
+
### Special Character Escaping
|
|
675
|
+
|
|
676
|
+
XML special characters are automatically escaped:
|
|
677
|
+
|
|
678
|
+
```typescript
|
|
679
|
+
private escapeXML(str: string): string {
|
|
680
|
+
return str
|
|
681
|
+
.replace(/&/g, '&') // & → &
|
|
682
|
+
.replace(/</g, '<') // < → <
|
|
683
|
+
.replace(/>/g, '>') // > → >
|
|
684
|
+
.replace(/"/g, '"') // " → "
|
|
685
|
+
.replace(/'/g, '''); // ' → '
|
|
686
|
+
}
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
**Example:**
|
|
690
|
+
|
|
691
|
+
```xml
|
|
692
|
+
<order>
|
|
693
|
+
<customer>
|
|
694
|
+
<name>José García</name>
|
|
695
|
+
<email>josé@example.com</email>
|
|
696
|
+
<notes>Special: & < > " 中文 🎉</notes>
|
|
697
|
+
</customer>
|
|
698
|
+
</order>
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
## Best Practices
|
|
702
|
+
|
|
703
|
+
### Error Handling Checklist
|
|
704
|
+
|
|
705
|
+
- [ ] Wrap all SDK operations in try-catch blocks
|
|
706
|
+
- [ ] Check error types with `instanceof`
|
|
707
|
+
- [ ] Use `error.toJSON()` for structured logging
|
|
708
|
+
- [ ] Check `error.isRetryable()` before retry logic
|
|
709
|
+
- [ ] Re-throw errors after handling (don't silence)
|
|
710
|
+
- [ ] Log with correlation IDs and context
|
|
711
|
+
- [ ] Monitor error rates and patterns
|
|
712
|
+
- [ ] Alert on high error frequencies
|
|
713
|
+
- [ ] Document error scenarios for your team
|
|
714
|
+
- [ ] Test error paths in your code
|
|
715
|
+
|
|
716
|
+
### Do's and Don'ts
|
|
717
|
+
|
|
718
|
+
#### ✅ DO
|
|
719
|
+
|
|
720
|
+
```typescript
|
|
721
|
+
// ✅ Always wrap in try-catch
|
|
722
|
+
try {
|
|
723
|
+
const result = await mapper.map(data);
|
|
724
|
+
} catch (error) {
|
|
725
|
+
logger.error('Mapping failed:', error instanceof IngestionError ? error.toJSON() : error);
|
|
726
|
+
throw error;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
// ✅ Check error types
|
|
730
|
+
if (error instanceof MappingError) {
|
|
731
|
+
logger.error('Mapping error:', { field: error.field, path: error.sourcePath });
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
// ✅ Use isRetryable()
|
|
735
|
+
if (error instanceof IngestionError && error.isRetryable()) {
|
|
736
|
+
return scheduleRetry();
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
// ✅ Log with context
|
|
740
|
+
logger.error('Processing failed', {
|
|
741
|
+
error: error.toJSON(),
|
|
742
|
+
orderId,
|
|
743
|
+
fileName,
|
|
744
|
+
correlationId
|
|
745
|
+
});
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
#### ❌ DON'T
|
|
749
|
+
|
|
750
|
+
```typescript
|
|
751
|
+
// ❌ Don't silence errors
|
|
752
|
+
try {
|
|
753
|
+
await processOrder(data);
|
|
754
|
+
} catch (error) {
|
|
755
|
+
// Do nothing - ERROR IS LOST!
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
// ❌ Don't retry permanent errors
|
|
759
|
+
if (error instanceof FileParsingError) {
|
|
760
|
+
await retryOperation(); // Won't succeed!
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
// ❌ Don't log without context
|
|
764
|
+
logger.error('Error occurred');
|
|
765
|
+
|
|
766
|
+
// ❌ Don't throw strings
|
|
767
|
+
throw 'Something went wrong'; // Use Error objects!
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
### Error Context Best Practices
|
|
771
|
+
|
|
772
|
+
Always include these in error logs:
|
|
773
|
+
|
|
774
|
+
1. **Timestamp** - When error occurred
|
|
775
|
+
2. **Correlation ID** - Track across systems
|
|
776
|
+
3. **Business context** - Order ID, customer ID, etc.
|
|
777
|
+
4. **Operation** - What was being attempted
|
|
778
|
+
5. **Attempt** - Retry attempt number
|
|
779
|
+
6. **Environment** - Dev, staging, production
|
|
780
|
+
7. **Version** - Application version
|
|
781
|
+
|
|
782
|
+
```typescript
|
|
783
|
+
logger.error('Order processing failed', {
|
|
784
|
+
timestamp: new Date().toISOString(),
|
|
785
|
+
correlationId: context.correlationId,
|
|
786
|
+
orderId: metadata.orderId,
|
|
787
|
+
customerId: metadata.customerId,
|
|
788
|
+
operation: 'processOrder',
|
|
789
|
+
attempt: retryAttempt,
|
|
790
|
+
environment: process.env.NODE_ENV,
|
|
791
|
+
version: process.env.APP_VERSION,
|
|
792
|
+
error: error instanceof IngestionError ? error.toJSON() : error.message
|
|
793
|
+
});
|
|
794
|
+
```
|
|
795
|
+
|
|
796
|
+
## Summary
|
|
797
|
+
|
|
798
|
+
### Key Concepts
|
|
799
|
+
|
|
800
|
+
1. **Fail-Fast** - One error stops everything, no partial data
|
|
801
|
+
2. **Error Hierarchy** - All ingestion errors extend `IngestionError`
|
|
802
|
+
3. **Error Codes** - Machine-readable codes for programmatic handling
|
|
803
|
+
4. **Retryability** - Use `isRetryable()` to determine retry strategy
|
|
804
|
+
5. **Structured Logging** - Use `toJSON()` for complete error data
|
|
805
|
+
6. **UTF-8 Support** - Automatic BOM removal and special character handling
|
|
806
|
+
|
|
807
|
+
### Quick Reference Table
|
|
808
|
+
|
|
809
|
+
| Error Class | When Thrown | Retryable | Key Properties |
|
|
810
|
+
|-------------|-------------|-----------|----------------|
|
|
811
|
+
| `FileParsingError` | XML/CSV/JSON parsing fails | ❌ No | `fileName`, `lineNumber` |
|
|
812
|
+
| `PathResolutionError` | Path doesn't exist in data | ❌ No | `path` |
|
|
813
|
+
| `MappingError` | Field mapping fails | ❌ No | `field`, `sourcePath` |
|
|
814
|
+
| `ResolverError` | Resolver transformation fails | ❌ No | `resolverName`, `fieldName`, `fieldPath`, `originalError` |
|
|
815
|
+
| `ValidationError` | Data validation fails | ❌ No | `validationErrors[]` |
|
|
816
|
+
| `ConfigurationError` | Invalid config | ❌ No | `configKey` |
|
|
817
|
+
| `FluentAPIError` | HTTP error (4xx/5xx) | ✅ Yes (5xx) | `statusCode`, `details` |
|
|
818
|
+
| `AuthenticationError` | Auth failed (after retries) | ❌ No | `statusCode` (401) |
|
|
819
|
+
| `BatchSubmissionError` | API submission fails | ✅ Yes | `jobId`, `batchId` |
|
|
820
|
+
| `GraphQLExecutionError` | GraphQL errors in response | ❌ No* | `graphqlErrors[]`, `query`, `variables` |
|
|
821
|
+
| `DataSourceError` | S3/SFTP operation fails | Depends† | `source`, `operation`, `details` |
|
|
822
|
+
| `IngestionError` (base) | Various ingestion issues | Depends | `code`, `context` |
|
|
823
|
+
|
|
824
|
+
**Notes:**
|
|
825
|
+
- *GraphQLExecutionError: Not retryable unless due to network issues (check extensions)
|
|
826
|
+
- †DataSourceError: Retryable if network/timeout error; S3/SFTP have built-in retry (v0.1.10+)
|
|
827
|
+
|
|
828
|
+
### Related Documentation
|
|
829
|
+
|
|
830
|
+
- [Module 1: Foundations](./error-handling-01-foundations.md) - Fail-fast principles
|
|
831
|
+
- [Module 2: Error Types](./error-handling-02-error-types.md) - Error class hierarchy
|
|
832
|
+
- [Module 3: UTF-8 Handling](./error-handling-03-utf8-handling.md) - UTF-8 encoding
|
|
833
|
+
- [Module 4: Error Scenarios](./error-handling-04-error-scenarios.md) - Real-world examples
|
|
834
|
+
- [Module 5: Calling Patterns](./error-handling-05-calling-patterns.md) - Code patterns
|
|
835
|
+
- [Module 6: Retry Strategies](./error-handling-06-retry-strategies.md) - Retry logic
|
|
836
|
+
- [Module 7: Monitoring](./error-handling-07-monitoring.md) - Logging best practices
|
|
837
|
+
|
|
838
|
+
## Need Help?
|
|
839
|
+
|
|
840
|
+
- 📖 Browse [Examples](../examples/)
|
|
841
|
+
- 🔍 Check [Error Scenarios](./error-handling-04-error-scenarios.md)
|
|
842
|
+
- 📋 Review [Quick Reference](../../../02-CORE-GUIDES/advanced-services/advanced-services-quick-reference.md)
|
|
843
|
+
- 🐛 Report issues at [GitHub](https://github.com/fluentcommerce/fc-connect-sdk/issues)
|
|
844
|
+
|
|
845
|
+
---
|
|
846
|
+
|
|
847
|
+
**Previous:** [← Module 7: Monitoring](./error-handling-07-monitoring.md)
|