Skip to content

Commit 313a731

Browse files
fix: render data import tree errors in a table (#1190)
* fix: create table for data import tree JSON Error * chore: ci-rerun * fix: update the changes * fix: remove extra function * fix: add error message * fix: update the error for json output * fix: preserve original error on invalid json payload --------- Co-authored-by: Cristian Dominguez <cdominguez@salesforce.com>
1 parent 72f505f commit 313a731

File tree

1 file changed

+68
-15
lines changed

1 file changed

+68
-15
lines changed

src/commands/data/import/tree.ts

Lines changed: 68 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
66
*/
77

8-
import { Messages } from '@salesforce/core';
8+
import { Messages, SfError } from '@salesforce/core';
99
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
10+
import { ensureString, isObject } from '@salesforce/ts-types';
1011
import { importFromPlan } from '../../../api/data/tree/importPlan.js';
1112
import { importFromFiles } from '../../../api/data/tree/importFiles.js';
1213
import { orgFlags } from '../../../flags.js';
13-
import type { ImportResult } from '../../../api/data/tree/importTypes.js';
14+
import type { ImportResult, TreeResponse } from '../../../api/data/tree/importTypes.js';
1415

1516
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
1617
const messages = Messages.loadMessages('@salesforce/plugin-data', 'tree.import');
@@ -49,19 +50,71 @@ export default class Import extends SfCommand<ImportResult[]> {
4950
const { flags } = await this.parse(Import);
5051

5152
const conn = flags['target-org'].getConnection(flags['api-version']);
52-
const results = flags.plan
53-
? await importFromPlan(conn, flags.plan)
54-
: await importFromFiles(conn, flags.files ?? []);
5553

56-
this.table({
57-
data: results,
58-
columns: [
59-
{ key: 'refId', name: 'Reference ID' },
60-
{ key: 'type', name: 'Type' },
61-
{ key: 'id', name: 'ID' },
62-
],
63-
title: 'Import Results',
64-
});
65-
return results;
54+
try {
55+
const results = flags.plan
56+
? await importFromPlan(conn, flags.plan)
57+
: await importFromFiles(conn, flags.files ?? []);
58+
59+
this.table({
60+
data: results,
61+
columns: [
62+
{ key: 'refId', name: 'Reference ID' },
63+
{ key: 'type', name: 'Type' },
64+
{ key: 'id', name: 'ID' },
65+
],
66+
title: 'Import Results',
67+
});
68+
return results;
69+
} catch (err) {
70+
const error = err as Error;
71+
if (
72+
error.cause &&
73+
error.cause instanceof Error &&
74+
'data' in error.cause &&
75+
isObject(error.cause.data) &&
76+
'message' in error.cause.data
77+
) {
78+
const getTreeResponse = (payload: string): TreeResponse => {
79+
try {
80+
return JSON.parse(payload) as TreeResponse;
81+
} catch (parseErr) {
82+
// throw original error on invalid JSON payload
83+
if (parseErr instanceof Error && parseErr.name === 'SyntaxError') {
84+
throw error;
85+
}
86+
throw parseErr;
87+
}
88+
};
89+
const errorData = getTreeResponse(ensureString(error.cause.data.message));
90+
91+
if (errorData.hasErrors) {
92+
const errorResults = errorData.results
93+
.map((result) =>
94+
result.errors.map((errors) => ({
95+
referenceId: result.referenceId,
96+
StatusCode: errors.statusCode,
97+
Message: errors.message,
98+
fields: errors.fields.join(', ') || 'N/A',
99+
}))
100+
)
101+
.flat();
102+
this.table({
103+
data: errorResults,
104+
columns: [
105+
{ key: 'referenceId', name: 'Reference ID' },
106+
{ key: 'StatusCode', name: 'Status Code' },
107+
{ key: 'Message', name: 'Error Message' },
108+
{ key: 'fields', name: 'Fields' },
109+
],
110+
title: 'Tree import errors',
111+
});
112+
const errors = new SfError('Data Import failed');
113+
errors.setData(errorResults);
114+
throw errors;
115+
}
116+
}
117+
throw error;
118+
}
66119
}
67120
}

0 commit comments

Comments
 (0)