Skip to content

Commit 490d15b

Browse files
authored
Merge pull request #167 from amtrack/feat/retry-listmetadata-for-single-query-when-chunk-failed
feat: retry listing metadata per query when a chunk of queries failed
2 parents 27475db + 8d22108 commit 490d15b

File tree

2 files changed

+51
-3
lines changed

2 files changed

+51
-3
lines changed

src/jsforce-utils.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,25 @@ export async function listMetadataInChunks(conn: Connection, queries: ListMetada
2929
const CHUNK_SIZE = 3;
3030
const result: FileProperties[] = [];
3131
for (const chunkOfQueries of chunk(queries, CHUNK_SIZE)) {
32-
const chunkOfMetadataComponents = await conn.metadata.list(chunkOfQueries);
33-
if (chunkOfMetadataComponents) {
34-
result.push(...ensureArray(chunkOfMetadataComponents));
32+
try {
33+
const chunkOfMetadataComponents = await conn.metadata.list(chunkOfQueries);
34+
if (chunkOfMetadataComponents) {
35+
result.push(...ensureArray(chunkOfMetadataComponents));
36+
}
37+
} catch (_) {
38+
// fall back to 1 query to identify root cause
39+
for (const query of chunkOfQueries) {
40+
try {
41+
const metadataComponents = await conn.metadata.list(query);
42+
result.push(...ensureArray(metadataComponents));
43+
} catch (e) {
44+
throw new Error(
45+
`Failed to list metadata components for ${query.type}${query.folder ? `:${query.folder}` : ""}: ${
46+
e.message
47+
}`,
48+
);
49+
}
50+
}
3551
}
3652
}
3753
return result;

test/jsforce-utils.e2e-spec.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { expect } from "chai";
2+
import { listMetadataInChunks } from "../src/jsforce-utils";
3+
import { Org } from "@salesforce/core";
4+
5+
describe("jsforce-utils", () => {
6+
describe("listMetadataInChunks()", () => {
7+
it("lists more than 4 queries in chunks of 3", async () => {
8+
const org = await Org.create({});
9+
const conn = org.getConnection();
10+
const result = await listMetadataInChunks(conn, [
11+
{ type: "ApexClass" },
12+
{ type: "CustomObject" },
13+
{ type: "ApexPage" },
14+
{ type: "ApexTrigger" },
15+
]);
16+
expect(result).length.to.be.greaterThanOrEqual(1);
17+
});
18+
it("retries per query when a chunk of queries failed", async () => {
19+
const org = await Org.create({});
20+
const conn = org.getConnection();
21+
let err;
22+
try {
23+
await listMetadataInChunks(conn, [{ type: "ThisTypeDoesNotExist" }]);
24+
} catch (e) {
25+
err = e;
26+
}
27+
expect(() => {
28+
throw err;
29+
}).to.throw(/Failed to list.*ThisTypeDoesNotExist.*INVALID_TYPE.*ThisTypeDoesNotExist/, err.message);
30+
});
31+
});
32+
});

0 commit comments

Comments
 (0)