-
Notifications
You must be signed in to change notification settings - Fork 138
Add retry to StandardValueSet query to fix network errors #652
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b7fbc02
c54d975
db8b729
227cd5f
63f8787
a0dec0a
926805c
332cfa8
57d120c
b2d6661
59066ce
e3d1d14
61591c6
5a0ff8d
70d7631
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ | |
*/ | ||
|
||
import { Connection, Logger } from '@salesforce/core'; | ||
import { retry, NotRetryableError, RetryError } from 'ts-retry-promise'; | ||
import { RegistryAccess, registry as defaultRegistry, MetadataType } from '../registry'; | ||
import { standardValueSet } from '../registry/standardvalueset'; | ||
import { FileProperties, StdValueSetRecord, ListMetadataQuery } from '../client/types'; | ||
|
@@ -108,10 +109,28 @@ export class ConnectionResolver { | |
if (query.type === defaultRegistry.types.standardvalueset.name && members.length === 0) { | ||
const standardValueSetPromises = standardValueSet.fullnames.map(async (standardValueSetFullName) => { | ||
try { | ||
const standardValueSetRecord: StdValueSetRecord = await this.connection.singleRecordQuery( | ||
`SELECT Id, MasterLabel, Metadata FROM StandardValueSet WHERE MasterLabel = '${standardValueSetFullName}'`, | ||
{ tooling: true } | ||
); | ||
// The 'singleRecordQuery' method was having connection errors, using `retry` resolves this | ||
// Note that this type of connection retry logic may someday be added to jsforce v2 | ||
// Once that happens this logic could be reverted | ||
const standardValueSetRecord: StdValueSetRecord = await retry(async () => { | ||
peternhale marked this conversation as resolved.
Show resolved
Hide resolved
|
||
try { | ||
return await this.connection.singleRecordQuery( | ||
`SELECT Id, MasterLabel, Metadata FROM StandardValueSet WHERE MasterLabel = '${standardValueSetFullName}'`, | ||
{ tooling: true } | ||
); | ||
} catch (err) { | ||
// We exit the retry loop with `NotRetryableError` if we get an (expected) unsupported metadata type error | ||
const error = err as Error; | ||
if (error.message.includes('either inaccessible or not supported in Metadata API')) { | ||
this.logger.debug('Expected error:', error.message); | ||
throw new NotRetryableError(error.message); | ||
} | ||
|
||
// Otherwise throw the err so we can retry again | ||
throw err; | ||
} | ||
}); | ||
|
||
return ( | ||
standardValueSetRecord.Metadata.standardValue.length && { | ||
fullName: standardValueSetRecord.MasterLabel, | ||
|
@@ -126,8 +145,15 @@ export class ConnectionResolver { | |
lastModifiedDate: '', | ||
} | ||
); | ||
} catch (error) { | ||
this.logger.debug((error as Error).message); | ||
} catch (err) { | ||
// error.message here will be overwritten by 'ts-retry-promise' | ||
// Example error.message from the library: "All retries failed" or "Met not retryable error" | ||
// 'ts-retry-promise' exposes the actual error on `error.lastError` | ||
const error = err as RetryError; | ||
|
||
if (error.lastError && error.lastError.message) { | ||
this.logger.debug(error.lastError.message); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we add a few unit tests to cover the conditions added here?
It would make the unit testing a bit cleaner if you refactored the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added some tests @gbockus-sf 👍 |
||
} | ||
}); | ||
for await (const standardValueSetResult of standardValueSetPromises) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a common thing to do for circular deps?
Does this not mean that for the tests source-tracking would be using the current version of SDR, but after deploy it'd be using whatever version it specifies in it's package.json?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
they're not circular, just transitive. plugin-source depends on SDR and STL and STL depends on SDR.
When we build the CLI, we bump both SDR and STL via yarn resolutions to their latest version.
This tests the changes on this branch everywhere that SDR is used. Imagine a bug in SDR that causes problems for STL, but you don't catch it because the nuts are using an STL with a different (bug-free) SDR. Wouldn't want to miss that!