diff --git a/packages/destination-actions/src/destinations/salesforce-marketing-cloud/_tests_/multistatus.test.ts b/packages/destination-actions/src/destinations/salesforce-marketing-cloud/_tests_/multistatus.test.ts index 48450e0d801..fd0f230430c 100644 --- a/packages/destination-actions/src/destinations/salesforce-marketing-cloud/_tests_/multistatus.test.ts +++ b/packages/destination-actions/src/destinations/salesforce-marketing-cloud/_tests_/multistatus.test.ts @@ -200,6 +200,71 @@ describe('Multistatus', () => { errorreporter: 'DESTINATION' }) }) + + it('should mark "Unable to save rows for data extension ID" error as retryable even if SFMC returns 400', async () => { + const errorResponse = { + status: 400, + message: 'Invalid keys for ID: HS1', + additionalErrors: [ + { + errorcode: 10006, + message: 'Unable to save rows for data extension ID' + } + ] + } + + nock(requestUrl).post('').reply(400, errorResponse) + + const events: SegmentEvent[] = [ + createTestEvent({ + type: 'track', + userId: 'harry-1', + properties: { + id: '1234567890', + keys: { + id: 'HS1' // Valid key + }, + values: { + name: 'Harry Styles' + } + } + }), + createTestEvent({ + type: 'track', + userId: 'harry-2', + properties: { + id: '1234567890', + keys: { + id: 'HS2' // Invalid key + }, + values: { + name: 'Harry Potter' + } + } + }) + ] + + const response = await testDestination.executeBatch('dataExtension', { + events, + settings, + mapping + }) + + expect(response[0]).toMatchObject({ + status: 500, + errortype: 'INTERNAL_SERVER_ERROR', + errormessage: 'Unable to save rows for data extension ID', + errorreporter: 'DESTINATION' + }) + + expect(response[1]).toMatchObject({ + status: 500, + errortype: 'INTERNAL_SERVER_ERROR', + errormessage: 'Unable to save rows for data extension ID', + errorreporter: 'DESTINATION' + }) + }) + it('should handle multistatus errors and set correct status code', async () => { const errorResponse = { status: 429, @@ -467,6 +532,72 @@ describe('Multistatus', () => { }) }) + it('should mark "Unable to save rows for data extension ID" error as retryable even if SFMC returns 400', async () => { + const errorResponse = { + status: 400, + message: 'Invalid keys for ID: HS1', + additionalErrors: [ + { + errorcode: 10006, + message: 'Unable to save rows for data extension ID' + } + ] + } + + nock(requestUrl).post('').reply(400, errorResponse) + + const events: SegmentEvent[] = [ + createTestEvent({ + type: 'track', + userId: 'harry-1', + properties: { + id: '1234567890', + keys: { + contactKey: 'harry-1', + id: 'HS1' + }, + values: { + name: 'Harry Styles' + } + } + }), + createTestEvent({ + type: 'track', + userId: 'harry-2', + properties: { + id: '1234567890', + keys: { + contactKey: 'harry-2', + id: 'HS2' + }, + values: { + name: 'Harry Potter' + } + } + }) + ] + + const response = await testDestination.executeBatch('contactDataExtension', { + events, + settings, + mapping + }) + + expect(response[0]).toMatchObject({ + status: 500, + errortype: 'INTERNAL_SERVER_ERROR', + errormessage: 'Unable to save rows for data extension ID', + errorreporter: 'DESTINATION' + }) + + expect(response[1]).toMatchObject({ + status: 500, + errortype: 'INTERNAL_SERVER_ERROR', + errormessage: 'Unable to save rows for data extension ID', + errorreporter: 'DESTINATION' + }) + }) + it('should handle multistatus errors and set correct status code', async () => { const errorResponse = { status: 429, diff --git a/packages/destination-actions/src/destinations/salesforce-marketing-cloud/sfmc-operations.ts b/packages/destination-actions/src/destinations/salesforce-marketing-cloud/sfmc-operations.ts index a111f86adce..273749a1814 100644 --- a/packages/destination-actions/src/destinations/salesforce-marketing-cloud/sfmc-operations.ts +++ b/packages/destination-actions/src/destinations/salesforce-marketing-cloud/sfmc-operations.ts @@ -141,9 +141,20 @@ export async function executeUpsertWithMultiStatus( err.response.data.additionalErrors.length > 0 && err.response.data.additionalErrors + const retryableCodes = [10006] + const hasAnyRetryableError = + additionalError && + additionalError.some( + (e) => retryableCodes.includes(e.errorcode) && e.message.includes('Unable to save rows for data extension ID') + ) + + let status = 500 // default status is 500 + if (!hasAnyRetryableError && err?.response?.status) { + status = err.response.status + } payloads.forEach((_, index) => { multiStatusResponse.setErrorResponseAtIndex(index, { - status: err?.response?.status || 500, + status: status, errormessage: additionalError ? additionalError[0].message : errData?.message || '', sent: rows[index] as Object as JSONLikeObject, /*