@contrail/flexplm 1.5.1-alpha.14abddb → 1.5.1-alpha.2e74ff1

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.
@@ -77,9 +77,10 @@ export declare class BaseProcessPublishAssortment {
77
77
  getResultsCount(events: any): any;
78
78
  private sendEvents;
79
79
  private sendToFlexPLM;
80
+ private buildPublishError;
80
81
  private saveToLocalFile;
81
82
  private handleVibeIQFile;
82
- sendPublishPayloadEvent(outboundEvent: any): Promise<void>;
83
+ private sendPublishPayloadEvent;
83
84
  private getCurrentDateString;
84
85
  getItemFamilyChanges(pcd: PublishChangeData, changeDetail: any, assortmentItemFullChangeMap: Map<string, any>, assortmentItemDeleteMap: Map<string, any>): Map<string, ItemFamilyChanges>;
85
86
  getEventsForPublishChangeData(publishChangeData: PublishChangeData): Promise<SeasonalPayload[]>;
@@ -576,12 +576,30 @@ class BaseProcessPublishAssortment {
576
576
  events
577
577
  };
578
578
  const flexPLMConnect = new flexplm_connect_1.FlexPLMConnect(this.config);
579
- const [result] = await Promise.all([
579
+ const [sendResult, eventResult] = await Promise.allSettled([
580
580
  flexPLMConnect.sendToFlexPLM(outboundPublishEvent),
581
581
  this.sendPublishPayloadEvent(outboundPublishEvent)
582
582
  ]);
583
- result['outboundPublishEvent'] = outboundPublishEvent;
584
- return result;
583
+ if (sendResult.status === 'rejected' || eventResult.status === 'rejected') {
584
+ throw this.buildPublishError(sendResult, eventResult, outboundPublishEvent);
585
+ }
586
+ const result = sendResult.value;
587
+ const isResultObject = typeof result === 'object' && result !== null;
588
+ return isResultObject
589
+ ? { ...result, outboundPublishEvent }
590
+ : { result, outboundPublishEvent };
591
+ }
592
+ buildPublishError(sendResult, eventResult, outboundPublishEvent) {
593
+ const baseReason = sendResult.status === 'rejected' ? sendResult.reason : eventResult.reason;
594
+ const error = baseReason instanceof Error ? baseReason : new Error(String(baseReason));
595
+ error.outboundPublishEvent = outboundPublishEvent;
596
+ error.sendToFlexPLMResult = sendResult.status === 'fulfilled'
597
+ ? sendResult.value
598
+ : { error: sendResult.reason?.message ?? String(sendResult.reason) };
599
+ error.sendPublishPayloadEventResult = eventResult.status === 'fulfilled'
600
+ ? eventResult.value
601
+ : { error: eventResult.reason?.message ?? String(eventResult.reason) };
602
+ return error;
585
603
  }
586
604
  async saveToLocalFile(events, eventType) {
587
605
  let results = {};
@@ -628,11 +646,18 @@ class BaseProcessPublishAssortment {
628
646
  };
629
647
  if (sendMode === 'vibeiqfile') {
630
648
  const flexPLMConnect = new flexplm_connect_1.FlexPLMConnect(this.config);
631
- const [result] = await Promise.all([
649
+ const [sendResult, eventResult] = await Promise.allSettled([
632
650
  flexPLMConnect.sendToFlexPLM(outboundPublishEvent),
633
651
  this.sendPublishPayloadEvent(outboundPublishEvent)
634
652
  ]);
635
- return { ...result, outboundPublishEvent };
653
+ if (sendResult.status === 'rejected' || eventResult.status === 'rejected') {
654
+ throw this.buildPublishError(sendResult, eventResult, outboundPublishEvent);
655
+ }
656
+ const result = sendResult.value;
657
+ const isResultObject = typeof result === 'object' && result !== null;
658
+ return isResultObject
659
+ ? { ...result, outboundPublishEvent }
660
+ : { result, outboundPublishEvent };
636
661
  }
637
662
  else {
638
663
  await this.sendPublishPayloadEvent(outboundPublishEvent);
@@ -642,7 +667,7 @@ class BaseProcessPublishAssortment {
642
667
  };
643
668
  }
644
669
  }
645
- async sendPublishPayloadEvent(outboundEvent) {
670
+ async sendPublishPayloadEvent(outboundPublishEvent) {
646
671
  console.info('sendPublishPayloadEvent()');
647
672
  let initialEvent = {};
648
673
  if (this.config?.event) {
@@ -653,7 +678,7 @@ class BaseProcessPublishAssortment {
653
678
  const eventBody = {
654
679
  originSystemType: 'VibeIQ',
655
680
  objectClass: 'AssortmentPublishedToFlexPLM',
656
- outboundEvent,
681
+ outboundPublishEvent,
657
682
  initialEvent
658
683
  };
659
684
  await new sdk_1.Entities().create({
@@ -1709,7 +1709,7 @@ describe('sendToFlexPLM / handleVibeIQFile / sendPublishPayloadEvent', () => {
1709
1709
  afterEach(() => {
1710
1710
  jest.restoreAllMocks();
1711
1711
  });
1712
- it('sendToFlexPLM merges outboundPublishEvent into result and calls sendPublishPayloadEvent in parallel', async () => {
1712
+ it('should merge outboundPublishEvent into result and call sendPublishPayloadEvent in parallel', async () => {
1713
1713
  const bppa = new base_process_publish_assortment_1.BaseProcessPublishAssortment(config, dc, mapFileUtil);
1714
1714
  const flexResponse = { status: 200, data: { ok: true } };
1715
1715
  let flexResolved = false;
@@ -1738,7 +1738,80 @@ describe('sendToFlexPLM / handleVibeIQFile / sendPublishPayloadEvent', () => {
1738
1738
  expect(spyEvent).toHaveBeenCalledWith(passedOutboundPublishEvent);
1739
1739
  expect(result).toEqual({ ...flexResponse, outboundPublishEvent: passedOutboundPublishEvent });
1740
1740
  });
1741
- it('handleVibeIQFile (vibeiqfile) merges outboundPublishEvent into FlexPLM result and calls sendPublishPayloadEvent', async () => {
1741
+ it('sendToFlexPLM throws when flexPLMConnect.sendToFlexPLM fails, attaching outboundPublishEvent and both results', async () => {
1742
+ const bppa = new base_process_publish_assortment_1.BaseProcessPublishAssortment(config, dc, mapFileUtil);
1743
+ const flexError = new Error('flex failed');
1744
+ const eventResponse = { eventOk: true };
1745
+ jest.spyOn(flexplm_connect_1.FlexPLMConnect.prototype, 'sendToFlexPLM').mockRejectedValue(flexError);
1746
+ jest.spyOn(bppa, 'sendPublishPayloadEvent').mockResolvedValue(eventResponse);
1747
+ await expect(bppa.sendToFlexPLM(events, eventType)).rejects.toMatchObject({
1748
+ message: 'flex failed',
1749
+ outboundPublishEvent: expect.objectContaining({ taskId: 'task-abc', eventType, objectClass: 'LCSSeason', events }),
1750
+ sendToFlexPLMResult: { error: 'flex failed' },
1751
+ sendPublishPayloadEventResult: eventResponse
1752
+ });
1753
+ });
1754
+ it('sendToFlexPLM throws when sendPublishPayloadEvent fails, with flex result attached', async () => {
1755
+ const bppa = new base_process_publish_assortment_1.BaseProcessPublishAssortment(config, dc, mapFileUtil);
1756
+ const flexResponse = { status: 200 };
1757
+ const eventError = new Error('event failed');
1758
+ jest.spyOn(flexplm_connect_1.FlexPLMConnect.prototype, 'sendToFlexPLM').mockResolvedValue(flexResponse);
1759
+ jest.spyOn(bppa, 'sendPublishPayloadEvent').mockRejectedValue(eventError);
1760
+ await expect(bppa.sendToFlexPLM(events, eventType)).rejects.toMatchObject({
1761
+ message: 'event failed',
1762
+ outboundPublishEvent: expect.objectContaining({ taskId: 'task-abc', eventType }),
1763
+ sendToFlexPLMResult: flexResponse,
1764
+ sendPublishPayloadEventResult: { error: 'event failed' }
1765
+ });
1766
+ });
1767
+ it('sendToFlexPLM throws the flexPLMConnect error when both fail', async () => {
1768
+ const bppa = new base_process_publish_assortment_1.BaseProcessPublishAssortment(config, dc, mapFileUtil);
1769
+ const flexError = new Error('flex failed');
1770
+ const eventError = new Error('event failed');
1771
+ jest.spyOn(flexplm_connect_1.FlexPLMConnect.prototype, 'sendToFlexPLM').mockRejectedValue(flexError);
1772
+ jest.spyOn(bppa, 'sendPublishPayloadEvent').mockRejectedValue(eventError);
1773
+ await expect(bppa.sendToFlexPLM(events, eventType)).rejects.toBe(flexError);
1774
+ expect(flexError.outboundPublishEvent).toBeDefined();
1775
+ expect(flexError.sendToFlexPLMResult).toEqual({ error: 'flex failed' });
1776
+ expect(flexError.sendPublishPayloadEventResult).toEqual({ error: 'event failed' });
1777
+ });
1778
+ it('handleVibeIQFile (vibeiqfile) throws when flexPLMConnect.sendToFlexPLM fails, with both results attached', async () => {
1779
+ const bppa = new base_process_publish_assortment_1.BaseProcessPublishAssortment(config, dc, mapFileUtil);
1780
+ const flexError = new Error('flex failed');
1781
+ const eventResponse = { eventOk: true };
1782
+ jest.spyOn(flexplm_connect_1.FlexPLMConnect.prototype, 'sendToFlexPLM').mockRejectedValue(flexError);
1783
+ jest.spyOn(bppa, 'sendPublishPayloadEvent').mockResolvedValue(eventResponse);
1784
+ await expect(bppa.handleVibeIQFile(events, eventType, 'vibeiqfile')).rejects.toMatchObject({
1785
+ message: 'flex failed',
1786
+ outboundPublishEvent: expect.objectContaining({ eventsFileId: 'file-123' }),
1787
+ sendToFlexPLMResult: { error: 'flex failed' },
1788
+ sendPublishPayloadEventResult: eventResponse
1789
+ });
1790
+ });
1791
+ it('handleVibeIQFile (vibeiqfile) throws when sendPublishPayloadEvent fails, with flex result attached', async () => {
1792
+ const bppa = new base_process_publish_assortment_1.BaseProcessPublishAssortment(config, dc, mapFileUtil);
1793
+ const flexResponse = { status: 200 };
1794
+ const eventError = new Error('event failed');
1795
+ jest.spyOn(flexplm_connect_1.FlexPLMConnect.prototype, 'sendToFlexPLM').mockResolvedValue(flexResponse);
1796
+ jest.spyOn(bppa, 'sendPublishPayloadEvent').mockRejectedValue(eventError);
1797
+ await expect(bppa.handleVibeIQFile(events, eventType, 'vibeiqfile')).rejects.toMatchObject({
1798
+ message: 'event failed',
1799
+ outboundPublishEvent: expect.objectContaining({ eventsFileId: 'file-123' }),
1800
+ sendToFlexPLMResult: flexResponse,
1801
+ sendPublishPayloadEventResult: { error: 'event failed' }
1802
+ });
1803
+ });
1804
+ it('handleVibeIQFile (vibeiqfile) throws the flexPLMConnect error when both fail', async () => {
1805
+ const bppa = new base_process_publish_assortment_1.BaseProcessPublishAssortment(config, dc, mapFileUtil);
1806
+ const flexError = new Error('flex failed');
1807
+ const eventError = new Error('event failed');
1808
+ jest.spyOn(flexplm_connect_1.FlexPLMConnect.prototype, 'sendToFlexPLM').mockRejectedValue(flexError);
1809
+ jest.spyOn(bppa, 'sendPublishPayloadEvent').mockRejectedValue(eventError);
1810
+ await expect(bppa.handleVibeIQFile(events, eventType, 'vibeiqfile')).rejects.toBe(flexError);
1811
+ expect(flexError.sendToFlexPLMResult).toEqual({ error: 'flex failed' });
1812
+ expect(flexError.sendPublishPayloadEventResult).toEqual({ error: 'event failed' });
1813
+ });
1814
+ it('should merge outboundPublishEvent into FlexPLM result and call sendPublishPayloadEvent when mode is vibeiqfile', async () => {
1742
1815
  const bppa = new base_process_publish_assortment_1.BaseProcessPublishAssortment(config, dc, mapFileUtil);
1743
1816
  const flexResponse = { status: 200, data: { ok: true } };
1744
1817
  const spyFlex = jest.spyOn(flexplm_connect_1.FlexPLMConnect.prototype, 'sendToFlexPLM')
@@ -1761,7 +1834,7 @@ describe('sendToFlexPLM / handleVibeIQFile / sendPublishPayloadEvent', () => {
1761
1834
  expect(spyEvent).toHaveBeenCalledWith(passedOutboundPublishEvent);
1762
1835
  expect(result).toEqual({ ...flexResponse, outboundPublishEvent: passedOutboundPublishEvent });
1763
1836
  });
1764
- it('handleVibeIQFile (vibeiqfile-dontsendtoflexplm) skips FlexPLM but still calls sendPublishPayloadEvent', async () => {
1837
+ it('should skip FlexPLM but still call sendPublishPayloadEvent when mode is vibeiqfile-dontsendtoflexplm', async () => {
1765
1838
  const bppa = new base_process_publish_assortment_1.BaseProcessPublishAssortment(config, dc, mapFileUtil);
1766
1839
  const spyFlex = jest.spyOn(flexplm_connect_1.FlexPLMConnect.prototype, 'sendToFlexPLM')
1767
1840
  .mockResolvedValue({});
@@ -1777,31 +1850,31 @@ describe('sendToFlexPLM / handleVibeIQFile / sendPublishPayloadEvent', () => {
1777
1850
  outboundPublishEvent: passedOutboundPublishEvent
1778
1851
  });
1779
1852
  });
1780
- it('sendPublishPayloadEvent creates an external-event with initialEvent parsed from config', async () => {
1853
+ it('should create an external-event with initialEvent parsed from config', async () => {
1781
1854
  const bppa = new base_process_publish_assortment_1.BaseProcessPublishAssortment(config, dc, mapFileUtil);
1782
- const outboundEvent = { foo: 'bar' };
1783
- await bppa.sendPublishPayloadEvent(outboundEvent);
1855
+ const outboundPublishEvent = { foo: 'bar' };
1856
+ await bppa.sendPublishPayloadEvent(outboundPublishEvent);
1784
1857
  expect(createCallArg).toEqual({
1785
1858
  entityName: 'external-event',
1786
1859
  object: {
1787
1860
  originSystemType: 'VibeIQ',
1788
1861
  objectClass: 'AssortmentPublishedToFlexPLM',
1789
- outboundEvent,
1862
+ outboundPublishEvent,
1790
1863
  initialEvent: { sourceEventId: 'src-1' }
1791
1864
  }
1792
1865
  });
1793
1866
  });
1794
- it('sendPublishPayloadEvent defaults initialEvent to {} when config has no event', async () => {
1867
+ it('should default initialEvent to {} when config has no event', async () => {
1795
1868
  const bareConfig = { taskId: 'task-x' };
1796
1869
  const bppa = new base_process_publish_assortment_1.BaseProcessPublishAssortment(bareConfig, dc, mapFileUtil);
1797
- const outboundEvent = { hello: 'world' };
1798
- await bppa.sendPublishPayloadEvent(outboundEvent);
1870
+ const outboundPublishEvent = { hello: 'world' };
1871
+ await bppa.sendPublishPayloadEvent(outboundPublishEvent);
1799
1872
  expect(createCallArg).toEqual({
1800
1873
  entityName: 'external-event',
1801
1874
  object: {
1802
1875
  originSystemType: 'VibeIQ',
1803
1876
  objectClass: 'AssortmentPublishedToFlexPLM',
1804
- outboundEvent,
1877
+ outboundPublishEvent,
1805
1878
  initialEvent: {}
1806
1879
  }
1807
1880
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrail/flexplm",
3
- "version": "1.5.1-alpha.14abddb",
3
+ "version": "1.5.1-alpha.2e74ff1",
4
4
  "description": "Library used for integration with flexplm.",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -2033,7 +2033,7 @@ describe('sendToFlexPLM / handleVibeIQFile / sendPublishPayloadEvent', () => {
2033
2033
  jest.restoreAllMocks();
2034
2034
  });
2035
2035
 
2036
- it('sendToFlexPLM merges outboundPublishEvent into result and calls sendPublishPayloadEvent in parallel', async () => {
2036
+ it('should merge outboundPublishEvent into result and call sendPublishPayloadEvent in parallel', async () => {
2037
2037
  const bppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
2038
2038
  const flexResponse = { status: 200, data: { ok: true } };
2039
2039
 
@@ -2045,7 +2045,7 @@ describe('sendToFlexPLM / handleVibeIQFile / sendPublishPayloadEvent', () => {
2045
2045
  flexResolved = true;
2046
2046
  return flexResponse as any;
2047
2047
  });
2048
- const spyEvent = jest.spyOn(bppa, 'sendPublishPayloadEvent')
2048
+ const spyEvent = jest.spyOn(bppa as any, 'sendPublishPayloadEvent')
2049
2049
  .mockImplementation(async () => {
2050
2050
  await new Promise(r => setTimeout(r, 5));
2051
2051
  eventResolved = true;
@@ -2067,13 +2067,104 @@ describe('sendToFlexPLM / handleVibeIQFile / sendPublishPayloadEvent', () => {
2067
2067
  expect(result).toEqual({ ...flexResponse, outboundPublishEvent: passedOutboundPublishEvent });
2068
2068
  });
2069
2069
 
2070
- it('handleVibeIQFile (vibeiqfile) merges outboundPublishEvent into FlexPLM result and calls sendPublishPayloadEvent', async () => {
2070
+ it('sendToFlexPLM throws when flexPLMConnect.sendToFlexPLM fails, attaching outboundPublishEvent and both results', async () => {
2071
+ const bppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
2072
+ const flexError = new Error('flex failed');
2073
+ const eventResponse = { eventOk: true };
2074
+
2075
+ jest.spyOn(FlexPLMConnect.prototype, 'sendToFlexPLM').mockRejectedValue(flexError);
2076
+ jest.spyOn(bppa as any, 'sendPublishPayloadEvent').mockResolvedValue(eventResponse as any);
2077
+
2078
+ await expect((bppa as any).sendToFlexPLM(events, eventType)).rejects.toMatchObject({
2079
+ message: 'flex failed',
2080
+ outboundPublishEvent: expect.objectContaining({ taskId: 'task-abc', eventType, objectClass: 'LCSSeason', events }),
2081
+ sendToFlexPLMResult: { error: 'flex failed' },
2082
+ sendPublishPayloadEventResult: eventResponse
2083
+ });
2084
+ });
2085
+
2086
+ it('sendToFlexPLM throws when sendPublishPayloadEvent fails, with flex result attached', async () => {
2087
+ const bppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
2088
+ const flexResponse = { status: 200 };
2089
+ const eventError = new Error('event failed');
2090
+
2091
+ jest.spyOn(FlexPLMConnect.prototype, 'sendToFlexPLM').mockResolvedValue(flexResponse as any);
2092
+ jest.spyOn(bppa as any, 'sendPublishPayloadEvent').mockRejectedValue(eventError);
2093
+
2094
+ await expect((bppa as any).sendToFlexPLM(events, eventType)).rejects.toMatchObject({
2095
+ message: 'event failed',
2096
+ outboundPublishEvent: expect.objectContaining({ taskId: 'task-abc', eventType }),
2097
+ sendToFlexPLMResult: flexResponse,
2098
+ sendPublishPayloadEventResult: { error: 'event failed' }
2099
+ });
2100
+ });
2101
+
2102
+ it('sendToFlexPLM throws the flexPLMConnect error when both fail', async () => {
2103
+ const bppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
2104
+ const flexError = new Error('flex failed');
2105
+ const eventError = new Error('event failed');
2106
+
2107
+ jest.spyOn(FlexPLMConnect.prototype, 'sendToFlexPLM').mockRejectedValue(flexError);
2108
+ jest.spyOn(bppa as any, 'sendPublishPayloadEvent').mockRejectedValue(eventError);
2109
+
2110
+ await expect((bppa as any).sendToFlexPLM(events, eventType)).rejects.toBe(flexError);
2111
+ expect((flexError as any).outboundPublishEvent).toBeDefined();
2112
+ expect((flexError as any).sendToFlexPLMResult).toEqual({ error: 'flex failed' });
2113
+ expect((flexError as any).sendPublishPayloadEventResult).toEqual({ error: 'event failed' });
2114
+ });
2115
+
2116
+ it('handleVibeIQFile (vibeiqfile) throws when flexPLMConnect.sendToFlexPLM fails, with both results attached', async () => {
2117
+ const bppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
2118
+ const flexError = new Error('flex failed');
2119
+ const eventResponse = { eventOk: true };
2120
+
2121
+ jest.spyOn(FlexPLMConnect.prototype, 'sendToFlexPLM').mockRejectedValue(flexError);
2122
+ jest.spyOn(bppa as any, 'sendPublishPayloadEvent').mockResolvedValue(eventResponse as any);
2123
+
2124
+ await expect((bppa as any).handleVibeIQFile(events, eventType, 'vibeiqfile')).rejects.toMatchObject({
2125
+ message: 'flex failed',
2126
+ outboundPublishEvent: expect.objectContaining({ eventsFileId: 'file-123' }),
2127
+ sendToFlexPLMResult: { error: 'flex failed' },
2128
+ sendPublishPayloadEventResult: eventResponse
2129
+ });
2130
+ });
2131
+
2132
+ it('handleVibeIQFile (vibeiqfile) throws when sendPublishPayloadEvent fails, with flex result attached', async () => {
2133
+ const bppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
2134
+ const flexResponse = { status: 200 };
2135
+ const eventError = new Error('event failed');
2136
+
2137
+ jest.spyOn(FlexPLMConnect.prototype, 'sendToFlexPLM').mockResolvedValue(flexResponse as any);
2138
+ jest.spyOn(bppa as any, 'sendPublishPayloadEvent').mockRejectedValue(eventError);
2139
+
2140
+ await expect((bppa as any).handleVibeIQFile(events, eventType, 'vibeiqfile')).rejects.toMatchObject({
2141
+ message: 'event failed',
2142
+ outboundPublishEvent: expect.objectContaining({ eventsFileId: 'file-123' }),
2143
+ sendToFlexPLMResult: flexResponse,
2144
+ sendPublishPayloadEventResult: { error: 'event failed' }
2145
+ });
2146
+ });
2147
+
2148
+ it('handleVibeIQFile (vibeiqfile) throws the flexPLMConnect error when both fail', async () => {
2149
+ const bppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
2150
+ const flexError = new Error('flex failed');
2151
+ const eventError = new Error('event failed');
2152
+
2153
+ jest.spyOn(FlexPLMConnect.prototype, 'sendToFlexPLM').mockRejectedValue(flexError);
2154
+ jest.spyOn(bppa as any, 'sendPublishPayloadEvent').mockRejectedValue(eventError);
2155
+
2156
+ await expect((bppa as any).handleVibeIQFile(events, eventType, 'vibeiqfile')).rejects.toBe(flexError);
2157
+ expect((flexError as any).sendToFlexPLMResult).toEqual({ error: 'flex failed' });
2158
+ expect((flexError as any).sendPublishPayloadEventResult).toEqual({ error: 'event failed' });
2159
+ });
2160
+
2161
+ it('should merge outboundPublishEvent into FlexPLM result and call sendPublishPayloadEvent when mode is vibeiqfile', async () => {
2071
2162
  const bppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
2072
2163
  const flexResponse = { status: 200, data: { ok: true } };
2073
2164
 
2074
2165
  const spyFlex = jest.spyOn(FlexPLMConnect.prototype, 'sendToFlexPLM')
2075
2166
  .mockResolvedValue(flexResponse as any);
2076
- const spyEvent = jest.spyOn(bppa, 'sendPublishPayloadEvent')
2167
+ const spyEvent = jest.spyOn(bppa as any, 'sendPublishPayloadEvent')
2077
2168
  .mockResolvedValue(undefined as any);
2078
2169
 
2079
2170
  const result = await (bppa as any).handleVibeIQFile(events, eventType, 'vibeiqfile');
@@ -2096,12 +2187,12 @@ describe('sendToFlexPLM / handleVibeIQFile / sendPublishPayloadEvent', () => {
2096
2187
  expect(result).toEqual({ ...flexResponse, outboundPublishEvent: passedOutboundPublishEvent });
2097
2188
  });
2098
2189
 
2099
- it('handleVibeIQFile (vibeiqfile-dontsendtoflexplm) skips FlexPLM but still calls sendPublishPayloadEvent', async () => {
2190
+ it('should skip FlexPLM but still call sendPublishPayloadEvent when mode is vibeiqfile-dontsendtoflexplm', async () => {
2100
2191
  const bppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
2101
2192
 
2102
2193
  const spyFlex = jest.spyOn(FlexPLMConnect.prototype, 'sendToFlexPLM')
2103
2194
  .mockResolvedValue({} as any);
2104
- const spyEvent = jest.spyOn(bppa, 'sendPublishPayloadEvent')
2195
+ const spyEvent = jest.spyOn(bppa as any, 'sendPublishPayloadEvent')
2105
2196
  .mockResolvedValue(undefined as any);
2106
2197
 
2107
2198
  const result = await (bppa as any).handleVibeIQFile(events, eventType, 'vibeiqfile-dontsendtoflexplm');
@@ -2117,36 +2208,36 @@ describe('sendToFlexPLM / handleVibeIQFile / sendPublishPayloadEvent', () => {
2117
2208
  });
2118
2209
  });
2119
2210
 
2120
- it('sendPublishPayloadEvent creates an external-event with initialEvent parsed from config', async () => {
2211
+ it('should create an external-event with initialEvent parsed from config', async () => {
2121
2212
  const bppa = new BaseProcessPublishAssortment(config, dc, mapFileUtil);
2122
- const outboundEvent = { foo: 'bar' };
2213
+ const outboundPublishEvent = { foo: 'bar' };
2123
2214
 
2124
- await bppa.sendPublishPayloadEvent(outboundEvent);
2215
+ await (bppa as any).sendPublishPayloadEvent(outboundPublishEvent);
2125
2216
 
2126
2217
  expect(createCallArg).toEqual({
2127
2218
  entityName: 'external-event',
2128
2219
  object: {
2129
2220
  originSystemType: 'VibeIQ',
2130
2221
  objectClass: 'AssortmentPublishedToFlexPLM',
2131
- outboundEvent,
2222
+ outboundPublishEvent,
2132
2223
  initialEvent: { sourceEventId: 'src-1' }
2133
2224
  }
2134
2225
  });
2135
2226
  });
2136
2227
 
2137
- it('sendPublishPayloadEvent defaults initialEvent to {} when config has no event', async () => {
2228
+ it('should default initialEvent to {} when config has no event', async () => {
2138
2229
  const bareConfig = { taskId: 'task-x' } as unknown as FCConfig;
2139
2230
  const bppa = new BaseProcessPublishAssortment(bareConfig, dc, mapFileUtil);
2140
- const outboundEvent = { hello: 'world' };
2231
+ const outboundPublishEvent = { hello: 'world' };
2141
2232
 
2142
- await bppa.sendPublishPayloadEvent(outboundEvent);
2233
+ await (bppa as any).sendPublishPayloadEvent(outboundPublishEvent);
2143
2234
 
2144
2235
  expect(createCallArg).toEqual({
2145
2236
  entityName: 'external-event',
2146
2237
  object: {
2147
2238
  originSystemType: 'VibeIQ',
2148
2239
  objectClass: 'AssortmentPublishedToFlexPLM',
2149
- outboundEvent,
2240
+ outboundPublishEvent,
2150
2241
  initialEvent: {}
2151
2242
  }
2152
2243
  });
@@ -693,12 +693,37 @@ export class BaseProcessPublishAssortment {
693
693
  };
694
694
 
695
695
  const flexPLMConnect = new FlexPLMConnect(this.config);
696
- const [result] = await Promise.all([
696
+ const [sendResult, eventResult] = await Promise.allSettled([
697
697
  flexPLMConnect.sendToFlexPLM(outboundPublishEvent),
698
698
  this.sendPublishPayloadEvent(outboundPublishEvent)
699
699
  ]);
700
- result['outboundPublishEvent'] = outboundPublishEvent;
701
- return result;
700
+
701
+ if (sendResult.status === 'rejected' || eventResult.status === 'rejected') {
702
+ throw this.buildPublishError(sendResult, eventResult, outboundPublishEvent);
703
+ }
704
+
705
+ const result = sendResult.value;
706
+ const isResultObject = typeof result === 'object' && result !== null;
707
+ return isResultObject
708
+ ? { ...result, outboundPublishEvent }
709
+ : { result, outboundPublishEvent };
710
+ }
711
+
712
+ private buildPublishError(
713
+ sendResult: PromiseSettledResult<any>,
714
+ eventResult: PromiseSettledResult<any>,
715
+ outboundPublishEvent: AsyncEventsPayloadType
716
+ ): Error {
717
+ const baseReason = sendResult.status === 'rejected' ? sendResult.reason : (eventResult as PromiseRejectedResult).reason;
718
+ const error: any = baseReason instanceof Error ? baseReason : new Error(String(baseReason));
719
+ error.outboundPublishEvent = outboundPublishEvent;
720
+ error.sendToFlexPLMResult = sendResult.status === 'fulfilled'
721
+ ? sendResult.value
722
+ : { error: sendResult.reason?.message ?? String(sendResult.reason) };
723
+ error.sendPublishPayloadEventResult = eventResult.status === 'fulfilled'
724
+ ? eventResult.value
725
+ : { error: eventResult.reason?.message ?? String(eventResult.reason) };
726
+ return error;
702
727
  }
703
728
 
704
729
  private async saveToLocalFile(events: SeasonalPayload[], eventType: string) {
@@ -752,11 +777,20 @@ export class BaseProcessPublishAssortment {
752
777
 
753
778
  if (sendMode === 'vibeiqfile') {
754
779
  const flexPLMConnect = new FlexPLMConnect(this.config);
755
- const [result] = await Promise.all([
780
+ const [sendResult, eventResult] = await Promise.allSettled([
756
781
  flexPLMConnect.sendToFlexPLM(outboundPublishEvent),
757
782
  this.sendPublishPayloadEvent(outboundPublishEvent)
758
783
  ]);
759
- return { ...result, outboundPublishEvent };
784
+
785
+ if (sendResult.status === 'rejected' || eventResult.status === 'rejected') {
786
+ throw this.buildPublishError(sendResult, eventResult, outboundPublishEvent);
787
+ }
788
+
789
+ const result = sendResult.value;
790
+ const isResultObject = typeof result === 'object' && result !== null;
791
+ return isResultObject
792
+ ? { ...result, outboundPublishEvent }
793
+ : { result, outboundPublishEvent };
760
794
  } else {
761
795
  await this.sendPublishPayloadEvent(outboundPublishEvent);
762
796
  return {
@@ -766,10 +800,10 @@ export class BaseProcessPublishAssortment {
766
800
  }
767
801
  }
768
802
 
769
- public async sendPublishPayloadEvent(outboundEvent: any){
803
+ private async sendPublishPayloadEvent(outboundPublishEvent: AsyncEventsPayloadType){
770
804
  console.info('sendPublishPayloadEvent()');
771
805
  let initialEvent = {};
772
- if(this.config?.event){
806
+ if (this.config?.event){
773
807
  initialEvent = (typeof this.config?.event === 'string')
774
808
  ? JSON.parse(this.config?.event)
775
809
  : this.config?.event;
@@ -777,7 +811,7 @@ export class BaseProcessPublishAssortment {
777
811
  const eventBody = {
778
812
  originSystemType: 'VibeIQ',
779
813
  objectClass: 'AssortmentPublishedToFlexPLM',
780
- outboundEvent,
814
+ outboundPublishEvent,
781
815
  initialEvent
782
816
  };
783
817