Skip to content

Commit

Permalink
fix(core): errors thrown when creating projects should prevent runnin…
Browse files Browse the repository at this point in the history
…g targets
  • Loading branch information
AgentEnder committed Apr 12, 2024
1 parent 2cb43ca commit 25581eb
Showing 1 changed file with 36 additions and 49 deletions.
85 changes: 36 additions & 49 deletions packages/nx/src/project-graph/plugins/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type {
} from './internal-api';
import type { CreateNodesContext, NxPlugin, NxPluginV2 } from './public-api';
import { AggregateCreateNodesError, CreateNodesError } from '../error-types';
import { throws } from 'node:assert';

export function isNxPluginV2(plugin: NxPlugin): plugin is NxPluginV2 {
return 'createNodes' in plugin || 'createDependencies' in plugin;
Expand Down Expand Up @@ -56,35 +57,38 @@ export async function runCreateNodesInParallel(
): Promise<CreateNodesResultWithContext[]> {
performance.mark(`${plugin.name}:createNodes - start`);

const promises: Array<
CreateNodesResultWithContext | Promise<CreateNodesResultWithContext>
> = configFiles.map((file) => {
performance.mark(`${plugin.name}:createNodes:${file} - start`);
// Result is either static or a promise, using Promise.resolve lets us
// handle both cases with same logic
const value = Promise.resolve(
plugin.createNodes[1](file, options, context)
);
return value
.catch((e) => {
performance.mark(`${plugin.name}:createNodes:${file} - end`);
return new CreateNodesError({
error: e,
pluginName: plugin.name,
file,
});
})
.then((r) => {
performance.mark(`${plugin.name}:createNodes:${file} - end`);
performance.measure(
`${plugin.name}:createNodes:${file}`,
`${plugin.name}:createNodes:${file} - start`,
`${plugin.name}:createNodes:${file} - end`
);
const errors: CreateNodesError[] = [];
const promises: Array<Promise<CreateNodesResultWithContext | null>> =
configFiles.map((file) => {
performance.mark(`${plugin.name}:createNodes:${file} - start`);
// Result is either static or a promise, using Promise.resolve lets us
// handle both cases with same logic
const value = Promise.resolve(
plugin.createNodes[1](file, options, context)
);
return value
.catch((e) => {
performance.mark(`${plugin.name}:createNodes:${file} - end`);
errors.push(
new CreateNodesError({
error: e,
pluginName: plugin.name,
file,
})
);
return null;
})
.then((r) => {
performance.mark(`${plugin.name}:createNodes:${file} - end`);
performance.measure(
`${plugin.name}:createNodes:${file}`,
`${plugin.name}:createNodes:${file} - start`,
`${plugin.name}:createNodes:${file} - end`
);

return { ...r, pluginName: plugin.name, file };
});
});
return { ...r, pluginName: plugin.name, file };
});
});
const results = await Promise.all(promises).then((results) => {
performance.mark(`${plugin.name}:createNodes - end`);
performance.measure(
Expand All @@ -95,29 +99,12 @@ export async function runCreateNodesInParallel(
return results;
});

const [errors, successful] = partition<
CreateNodesError,
CreateNodesResultWithContext
>(results, (r): r is CreateNodesError => r instanceof CreateNodesError);
const successful = results.filter(
(r): r is CreateNodesResultWithContext => r !== null
);

if (errors.length > 0) {
throw new AggregateCreateNodesError(plugin.name, errors, successful);
}
return results;
}

function partition<T, T2 = T>(
arr: Array<T | T2>,
test: (item: T | T2) => item is T
): [T[], T2[]] {
const pass: T[] = [];
const fail: T2[] = [];
for (const item of arr) {
if (test(item)) {
pass.push(item);
} else {
fail.push(item as any as T2);
}
}
return [pass, fail];
return successful;
}

0 comments on commit 25581eb

Please sign in to comment.