Skip to content

Commit 6e778e6

Browse files
authored
Sm/mdapi-fault-handler (#642)
* feat: handle transient mdapi error * chore: auto-update metadata coverage in METADATA_SUPPORT.md * test: mdapi error handling
1 parent 69b53ea commit 6e778e6

File tree

3 files changed

+21
-0
lines changed

3 files changed

+21
-0
lines changed

METADATA_SUPPORT.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,9 @@ v56 introduces the following new types. Here's their current level of support
511511
|:---|:---|:---|
512512
|AccountingSettings|||
513513
|CollectionsDashboardSettings|||
514+
|CustomizablePropensityScoringSettings|||
514515
|MfgServiceConsoleSettings|||
516+
|OauthOidcSettings|||
515517

516518
## Additional Types
517519

src/client/metadataTransfer.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,13 @@ export abstract class MetadataTransfer<Status extends MetadataRequestStatus, Res
217217
}
218218
} catch (e) {
219219
this.logger.error(e);
220+
// tolerate a known mdapi problem 500/INVALID_CROSS_REFERENCE_KEY: invalid cross reference id
221+
// that happens when request moves out of Pending
222+
if (e instanceof Error && e.name === 'JsonParseError') {
223+
this.logger.debug('Metadata API response not parseable', e);
224+
await Lifecycle.getInstance().emitWarning('Metadata API response not parseable');
225+
return { completed: false };
226+
}
220227
// tolerate intermittent network errors upto retry limit
221228
if (
222229
['ETIMEDOUT', 'ENOTFOUND', 'ECONNRESET', 'socket hang up'].some((retryableNetworkError) =>

test/client/metadataTransfer.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,18 @@ describe('MetadataTransfer', () => {
300300
expect(checkStatus.callCount).to.equal(3);
301301
});
302302

303+
it('should tolerate known mdapi error', async () => {
304+
const { checkStatus } = operation.lifecycle;
305+
const networkError1 = new Error('foo');
306+
networkError1.name = 'JsonParseError';
307+
checkStatus.onFirstCall().throws(networkError1);
308+
checkStatus.onSecondCall().throws(networkError1);
309+
checkStatus.onThirdCall().resolves({ done: true });
310+
311+
await operation.pollStatus();
312+
expect(checkStatus.callCount).to.equal(3);
313+
});
314+
303315
it('should throw wrapped error if there are no error listeners', async () => {
304316
const { checkStatus } = operation.lifecycle;
305317
const originalError = new Error('whoops');

0 commit comments

Comments
 (0)