diff --git a/.github/workflows/create-hotfix-branch.yml b/.github/workflows/create-hotfix-branch.yml index 994283a9f43..3cdc27609ee 100644 --- a/.github/workflows/create-hotfix-branch.yml +++ b/.github/workflows/create-hotfix-branch.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest # Only allow these users to create new hotfix branch from 'main' - if: github.ref == 'refs/heads/main' && (github.actor == 'ItsSudip' || github.actor == 'krishna2020' || github.actor == 'koladilip' || github.actor == 'saikumarrs' || github.actor == 'sandeepdsvs' || github.actor == 'shrouti1507' || github.actor == 'anantjain45823' || github.actor == 'chandumlg' || github.actor == 'mihir-4116' || github.actor == 'utsabc') && (github.triggering_actor == 'ItsSudip' || github.triggering_actor == 'krishna2020' || github.triggering_actor == 'saikumarrs' || github.triggering_actor == 'sandeepdsvs' || github.triggering_actor == 'koladilip' || github.triggering_actor == 'shrouti1507' || github.triggering_actor == 'anantjain45823' || github.triggering_actor == 'chandumlg' || github.triggering_actor == 'mihir-4116' || github.triggering_actor == 'sanpj2292' || github.triggering_actor == 'utsabc') + if: github.ref == 'refs/heads/main' && (github.actor == 'vinayteki95' || github.actor == 'ItsSudip' || github.actor == 'krishna2020' || github.actor == 'koladilip' || github.actor == 'saikumarrs' || github.actor == 'sandeepdsvs' || github.actor == 'shrouti1507' || github.actor == 'anantjain45823' || github.actor == 'chandumlg' || github.actor == 'mihir-4116' || github.actor == 'utsabc') && (github.triggering_actor == 'ItsSudip' || github.triggering_actor == 'krishna2020' || github.triggering_actor == 'saikumarrs' || github.triggering_actor == 'sandeepdsvs' || github.triggering_actor == 'koladilip' || github.triggering_actor == 'shrouti1507' || github.triggering_actor == 'anantjain45823' || github.triggering_actor == 'chandumlg' || github.triggering_actor == 'mihir-4116' || github.triggering_actor == 'sanpj2292' || github.triggering_actor == 'utsabc' || github.triggering_actor == 'vinayteki95') steps: - name: Create Branch uses: peterjgrainger/action-create-branch@v2.4.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e0c2254396..9b6530b7e52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,16 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [1.90.2](https://github.com/rudderlabs/rudder-transformer/compare/v1.90.1...v1.90.2) (2025-02-11) + + +### Bug Fixes + +* better error handling in webhook v2 ([9f224ec](https://github.com/rudderlabs/rudder-transformer/commit/9f224ec03b91f1a4d85b117dbf6972bb1ef40c6d)) +* improve error handling for webhook v2 ([f44d5a5](https://github.com/rudderlabs/rudder-transformer/commit/f44d5a56fd6ee183aea73eaba7e73c121f8bc470)) +* improve error handling for webhook v2 ([#4061](https://github.com/rudderlabs/rudder-transformer/issues/4061)) ([5d1e1bd](https://github.com/rudderlabs/rudder-transformer/commit/5d1e1bdb26bacddb3838bd16752b333d7814c294)) +* improve error handling for webhook v2 ([#4062](https://github.com/rudderlabs/rudder-transformer/issues/4062)) ([d795830](https://github.com/rudderlabs/rudder-transformer/commit/d79583087e98d713afb9b38d3a25d4e580a36c76)) + ### [1.90.1](https://github.com/rudderlabs/rudder-transformer/compare/v1.90.0...v1.90.1) (2025-02-06) diff --git a/package-lock.json b/package-lock.json index 319c5b43aa8..8ce4e55978e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "rudder-transformer", - "version": "1.90.1", + "version": "1.90.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "rudder-transformer", - "version": "1.90.1", + "version": "1.90.2", "license": "ISC", "dependencies": { "@amplitude/ua-parser-js": "0.7.24", diff --git a/package.json b/package.json index b6fb5b42884..87531f00ebb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rudder-transformer", - "version": "1.90.1", + "version": "1.90.2", "description": "", "homepage": "https://github.com/rudderlabs/rudder-transformer#readme", "bugs": { diff --git a/src/constants/index.js b/src/constants/index.js index f8ca53a94c9..05a258ee646 100644 --- a/src/constants/index.js +++ b/src/constants/index.js @@ -55,6 +55,10 @@ const HTTP_CUSTOM_STATUS_CODES = { FILTERED: 298, }; +const ErrorMessages = { + JSONParseError: 'Malformed JSON in request body', +}; + module.exports = { EventType, GENERIC_TRUE_VALUES, @@ -64,4 +68,5 @@ module.exports = { TraitsMapping, WhiteListedTraits, HTTP_CUSTOM_STATUS_CODES, + ErrorMessages, }; diff --git a/src/controllers/util/conversionStrategies/strategyV2ToV0.ts b/src/controllers/util/conversionStrategies/strategyV2ToV0.ts index 1145cf97632..2c91d82e403 100644 --- a/src/controllers/util/conversionStrategies/strategyV2ToV0.ts +++ b/src/controllers/util/conversionStrategies/strategyV2ToV0.ts @@ -1,17 +1,32 @@ +import { TransformationError } from '@rudderstack/integrations-lib'; import { SourceInputConversionResult, SourceInputV2 } from '../../../types'; import { VersionConversionStrategy } from './abstractions'; +import { ErrorMessages } from '../../../constants'; export class StrategyV2ToV0 extends VersionConversionStrategy> { convert(sourceEvents: SourceInputV2[]): SourceInputConversionResult>[] { - return sourceEvents.map((sourceEvent) => { - try { - const v0Event = JSON.parse(sourceEvent.request.body); - return { output: v0Event }; - } catch (err) { - const conversionError = - err instanceof Error ? err : new Error('error converting v2 to v0 spec'); - return { conversionError }; - } - }); + return sourceEvents.map((sourceEvent) => this.convertSingleEvent(sourceEvent)); + } + + private convertSingleEvent( + sourceEvent: SourceInputV2, + ): SourceInputConversionResult> { + try { + const v0Event = this.parseRequestBody(sourceEvent.request.body); + return { output: v0Event }; + } catch (err) { + const conversionError = + err instanceof TransformationError ? err : new Error('error converting v2 to v0 spec'); + + return { conversionError }; + } + } + + private parseRequestBody(body: string): NonNullable { + try { + return JSON.parse(body); + } catch (err) { + throw new TransformationError(ErrorMessages.JSONParseError); + } } } diff --git a/src/controllers/util/conversionStrategies/strategyV2ToV1.ts b/src/controllers/util/conversionStrategies/strategyV2ToV1.ts index 52cade0d9d3..068bc4ce63a 100644 --- a/src/controllers/util/conversionStrategies/strategyV2ToV1.ts +++ b/src/controllers/util/conversionStrategies/strategyV2ToV1.ts @@ -1,17 +1,31 @@ +import { TransformationError } from '@rudderstack/integrations-lib'; import { SourceInput, SourceInputConversionResult, SourceInputV2 } from '../../../types'; import { VersionConversionStrategy } from './abstractions'; export class StrategyV2ToV1 extends VersionConversionStrategy { convert(sourceEvents: SourceInputV2[]): SourceInputConversionResult[] { - return sourceEvents.map((sourceEvent) => { - try { - const v1Event = { event: JSON.parse(sourceEvent.request.body), source: sourceEvent.source }; - return { output: v1Event }; - } catch (err) { - const conversionError = - err instanceof Error ? err : new Error('error converting v2 to v1 spec'); - return { conversionError }; - } - }); + return sourceEvents.map((sourceEvent) => this.convertSingleEvent(sourceEvent)); + } + + private convertSingleEvent(sourceEvent: SourceInputV2): SourceInputConversionResult { + try { + const v1Event = { + event: this.parseRequestBody(sourceEvent.request.body), + source: sourceEvent.source, + }; + return { output: v1Event }; + } catch (err) { + const conversionError = + err instanceof TransformationError ? err : new Error('error converting v2 to v1 spec'); + return { conversionError }; + } + } + + private parseRequestBody(body: string): NonNullable { + try { + return JSON.parse(body); + } catch (err) { + throw new TransformationError('Malformed JSON in request body'); + } } } diff --git a/src/controllers/util/index.test.ts b/src/controllers/util/index.test.ts index 4559bccc523..1f53ba3c1b3 100644 --- a/src/controllers/util/index.test.ts +++ b/src/controllers/util/index.test.ts @@ -1,3 +1,5 @@ +import { TransformationError } from '@rudderstack/integrations-lib'; +import { ErrorMessages } from '../../constants'; import { Destination, Metadata, @@ -222,7 +224,7 @@ describe('adaptInputToVersion', () => { implementationVersion: 'v0', input: [ { - conversionError: new SyntaxError('Unexpected end of JSON input'), + conversionError: new TransformationError(ErrorMessages.JSONParseError), }, ], }; @@ -321,7 +323,7 @@ describe('adaptInputToVersion', () => { implementationVersion: 'v1', input: [ { - conversionError: new SyntaxError('Unexpected end of JSON input'), + conversionError: new TransformationError(ErrorMessages.JSONParseError), }, ], }; diff --git a/src/services/source/nativeIntegration.ts b/src/services/source/nativeIntegration.ts index 078716df96c..6b590a62e4f 100644 --- a/src/services/source/nativeIntegration.ts +++ b/src/services/source/nativeIntegration.ts @@ -2,6 +2,7 @@ import { FetchHandler } from '../../helpers/fetchHandlers'; import { SourceService } from '../../interfaces/SourceService'; import { ErrorDetailer, + ErrorDetailerOptions, MetaTransferObject, RudderMessage, SourceInputConversionResult, @@ -15,13 +16,14 @@ import { SourcePostTransformationService } from './postTransformation'; import logger from '../../logger'; export class NativeIntegrationSourceService implements SourceService { - public getTags(): MetaTransferObject { + public getTags(extraErrorDetails: ErrorDetailerOptions = {}): MetaTransferObject { const metaTO = { errorDetails: { module: tags.MODULES.SOURCE, implementation: tags.IMPLEMENTATIONS.NATIVE, destinationId: 'Non determinable', workspaceId: 'Non determinable', + ...extraErrorDetails, } as ErrorDetailer, errorContext: '[Native Integration Service] Failure During Source Transform', } as MetaTransferObject; @@ -36,7 +38,7 @@ export class NativeIntegrationSourceService implements SourceService { _requestMetadata: NonNullable, ): Promise { const sourceHandler = FetchHandler.getSourceHandler(sourceType, version); - const metaTO = this.getTags(); + const metaTO = this.getTags({ srcType: sourceType }); const respList: SourceTransformationResponse[] = await Promise.all( sourceEvents.map(async (sourceEvent) => { try { diff --git a/src/types/index.ts b/src/types/index.ts index a8e05d3ed62..59bee82f422 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -270,6 +270,9 @@ type ErrorDetailer = { module: string; implementation: string; feature: string; +} & ErrorDetailerOptions; + +type ErrorDetailerOptions = { errorCategory?: string; errorType?: string; meta?: string; @@ -390,6 +393,7 @@ export { Connection, Destination, ErrorDetailer, + ErrorDetailerOptions, MessageIdMetadataMap, MetaTransferObject, Metadata, diff --git a/test/integrations/sources/adjust/data.ts b/test/integrations/sources/adjust/data.ts index bfd61d4ed32..e898692a2d0 100644 --- a/test/integrations/sources/adjust/data.ts +++ b/test/integrations/sources/adjust/data.ts @@ -120,6 +120,7 @@ export const data = [ errorCategory: 'transformation', implementation: 'native', module: 'source', + srcType: 'adjust', workspaceId: 'Non determinable', }, statusCode: 400, @@ -176,6 +177,7 @@ export const data = [ errorCategory: 'transformation', implementation: 'native', module: 'source', + srcType: 'adjust', workspaceId: 'Non determinable', }, statusCode: 400, diff --git a/test/integrations/sources/appsflyer/data.ts b/test/integrations/sources/appsflyer/data.ts index 5ec64a07a87..c0e0bcc94fa 100644 --- a/test/integrations/sources/appsflyer/data.ts +++ b/test/integrations/sources/appsflyer/data.ts @@ -687,6 +687,7 @@ export const data = [ errorCategory: 'transformation', implementation: 'native', module: 'source', + srcType: 'appsflyer', workspaceId: 'Non determinable', }, statusCode: 400, diff --git a/test/integrations/sources/canny/data.ts b/test/integrations/sources/canny/data.ts index ac471904f93..50a99bb4832 100644 --- a/test/integrations/sources/canny/data.ts +++ b/test/integrations/sources/canny/data.ts @@ -1573,6 +1573,7 @@ export const data = [ errorCategory: 'transformation', implementation: 'native', module: 'source', + srcType: 'canny', workspaceId: 'Non determinable', }, }, @@ -1650,6 +1651,7 @@ export const data = [ errorCategory: 'transformation', implementation: 'native', module: 'source', + srcType: 'canny', workspaceId: 'Non determinable', }, }, diff --git a/test/integrations/sources/gainsightpx/data.ts b/test/integrations/sources/gainsightpx/data.ts index b0380015800..b3e3147ea9c 100644 --- a/test/integrations/sources/gainsightpx/data.ts +++ b/test/integrations/sources/gainsightpx/data.ts @@ -853,6 +853,7 @@ export const data = [ errorCategory: 'transformation', implementation: 'native', module: 'source', + srcType: 'gainsightpx', workspaceId: 'Non determinable', }, statusCode: 400, diff --git a/test/integrations/sources/iterable/data.ts b/test/integrations/sources/iterable/data.ts index 8912c83434a..e544cd2bc33 100644 --- a/test/integrations/sources/iterable/data.ts +++ b/test/integrations/sources/iterable/data.ts @@ -101,6 +101,7 @@ export const data = [ errorCategory: 'transformation', implementation: 'native', module: 'source', + srcType: 'iterable', workspaceId: 'Non determinable', }, statusCode: 400, @@ -145,6 +146,7 @@ export const data = [ errorCategory: 'transformation', implementation: 'native', module: 'source', + srcType: 'iterable', workspaceId: 'Non determinable', }, statusCode: 400, diff --git a/test/integrations/sources/shopify/data.ts b/test/integrations/sources/shopify/data.ts index fdf20094921..1cc10371daf 100644 --- a/test/integrations/sources/shopify/data.ts +++ b/test/integrations/sources/shopify/data.ts @@ -65,6 +65,7 @@ const serverSideEventsScenarios = [ errorCategory: 'transformation', implementation: 'native', module: 'source', + srcType: 'shopify', workspaceId: 'Non determinable', }, statusCode: 400, @@ -104,6 +105,7 @@ const serverSideEventsScenarios = [ errorCategory: 'transformation', implementation: 'native', module: 'source', + srcType: 'shopify', workspaceId: 'Non determinable', }, statusCode: 400, @@ -148,6 +150,7 @@ const serverSideEventsScenarios = [ errorCategory: 'transformation', implementation: 'native', module: 'source', + srcType: 'shopify', workspaceId: 'Non determinable', }, statusCode: 400,