feat(core): better formatting of project-graph related error messages

This commit is contained in:
Victor Savkin 2022-08-23 15:02:35 -04:00
parent 0d0b28a988
commit b6c9c1210c
14 changed files with 65 additions and 29 deletions

View File

@ -183,24 +183,20 @@ jobs:
npx nx-cloud record yarn nx format:check --base=$NX_BASE --head=$NX_HEAD && npx nx-cloud record yarn nx format:check --base=$NX_BASE --head=$NX_HEAD &&
npx nx-cloud record yarn check-commit && npx nx-cloud record yarn check-commit &&
npx nx-cloud record yarn check-lock-files && npx nx-cloud record yarn check-lock-files &&
npx nx-cloud record yarn nx workspace-lint &&
npx nx-cloud record yarn depcheck) & npx nx-cloud record yarn depcheck) &
pids+=($!) pids+=($!)
(yarn nx affected --target=build --base=$NX_BASE --head=$NX_HEAD --parallel=3 && (yarn nx affected --target=build --base=$NX_BASE --head=$NX_HEAD --parallel=3 &&
npx nx affected --target=e2e --base=$NX_BASE --head=$NX_HEAD --exclude=e2e-storybook,e2e-storybook-angular,e2e-react-native,e2e-detox,e2e-make-angular-cli-faster --parallel=1) & npx nx affected --target=e2e --base=$NX_BASE --head=$NX_HEAD --exclude=e2e-storybook,e2e-storybook-angular,e2e-react-native,e2e-detox,e2e-make-angular-cli-faster --parallel=1) &
pids+=($!) pids+=($!)
(npx nx-cloud record yarn nx workspace-lint && yarn nx affected --target=lint --base=$NX_BASE --head=$NX_HEAD --parallel=3) & yarn nx affected --target=lint --base=$NX_BASE --head=$NX_HEAD --parallel=3 &
pids+=($!) pids+=($!)
yarn nx affected --target=test --base=$NX_BASE --head=$NX_HEAD --parallel=1 & yarn nx affected --target=test --base=$NX_BASE --head=$NX_HEAD --parallel=1 &
pids+=($!) pids+=($!)
for pid in "${pids[@]}"; do for pid in "${pids[@]}"; do
wait "$pid" wait "$pid"
done done
- run:
name: Stop All Running Agents for This CI Run
command: npx nx-cloud stop-all-agents
when: always
# ------------------------- # -------------------------
# JOBS: Main-MacOS # JOBS: Main-MacOS
# ------------------------- # -------------------------
@ -237,10 +233,6 @@ jobs:
echo "Skipping E2E tests"; echo "Skipping E2E tests";
fi fi
no_output_timeout: 45m no_output_timeout: 45m
- run:
name: Stop All Running Agents for This CI Run
command: npx nx-cloud stop-all-agents
when: always
# ------------------------- # -------------------------
# WORKFLOWS(JOBS) # WORKFLOWS(JOBS)

View File

@ -901,7 +901,7 @@ Convert an Nx Generator into an Angular Devkit Schematic.
### createProjectGraphAsync ### createProjectGraphAsync
**createProjectGraphAsync**(): `Promise`<[`ProjectGraph`](../../devkit/index#projectgraph)\> **createProjectGraphAsync**(`opts?`): `Promise`<[`ProjectGraph`](../../devkit/index#projectgraph)\>
Computes and returns a ProjectGraph. Computes and returns a ProjectGraph.
@ -925,6 +925,13 @@ Tip: If you want to debug project graph creation, run your command with NX_DAEMO
Nx uses two layers of caching: the information about explicit dependencies stored on the disk and the information Nx uses two layers of caching: the information about explicit dependencies stored on the disk and the information
stored in the daemon process. To reset both run: `nx reset`. stored in the daemon process. To reset both run: `nx reset`.
#### Parameters
| Name | Type |
| :----------------- | :-------- |
| `opts` | `Object` |
| `opts.exitOnError` | `boolean` |
#### Returns #### Returns
`Promise`<[`ProjectGraph`](../../devkit/index#projectgraph)\> `Promise`<[`ProjectGraph`](../../devkit/index#projectgraph)\>

File diff suppressed because one or more lines are too long

View File

@ -42,7 +42,7 @@ export async function affected(
await connectToNxCloudUsingScan(nxArgs.scan); await connectToNxCloudUsingScan(nxArgs.scan);
const projectGraph = await createProjectGraphAsync(); const projectGraph = await createProjectGraphAsync({ exitOnError: true });
const projects = projectsToRun(nxArgs, projectGraph); const projects = projectsToRun(nxArgs, projectGraph);
try { try {

View File

@ -167,7 +167,9 @@ export async function generateGraph(
}, },
affectedProjects: string[] affectedProjects: string[]
): Promise<void> { ): Promise<void> {
let graph = pruneExternalNodes(await createProjectGraphAsync()); let graph = pruneExternalNodes(
await createProjectGraphAsync({ exitOnError: true })
);
const layout = workspaceLayout(); const layout = workspaceLayout();
const projects = Object.values(graph.nodes) as ProjectGraphProjectNode[]; const projects = Object.values(graph.nodes) as ProjectGraphProjectNode[];
@ -477,7 +479,9 @@ async function createDepGraphClientResponse(
performance.mark('project graph watch calculation:start'); performance.mark('project graph watch calculation:start');
await defaultFileHasher.init(); await defaultFileHasher.init();
let graph = pruneExternalNodes(await createProjectGraphAsync()); let graph = pruneExternalNodes(
await createProjectGraphAsync({ exitOnError: true })
);
performance.mark('project graph watch calculation:end'); performance.mark('project graph watch calculation:end');
performance.mark('project graph response generation:start'); performance.mark('project graph response generation:start');

View File

@ -79,7 +79,7 @@ export async function format(
async function getPatterns( async function getPatterns(
args: NxArgs & { libsAndApps: boolean; _: string[] } args: NxArgs & { libsAndApps: boolean; _: string[] }
): Promise<string[]> { ): Promise<string[]> {
const graph = await createProjectGraphAsync(); const graph = await createProjectGraphAsync({ exitOnError: true });
const allFilesPattern = ['.']; const allFilesPattern = ['.'];
if (args.all) { if (args.all) {
@ -119,7 +119,7 @@ async function getPatternsFromApps(
allWorkspaceFiles: FileData[], allWorkspaceFiles: FileData[],
projectGraph: ProjectGraph projectGraph: ProjectGraph
): Promise<string[]> { ): Promise<string[]> {
const graph = await createProjectGraphAsync(); const graph = await createProjectGraphAsync({ exitOnError: true });
const affectedGraph = filterAffected( const affectedGraph = filterAffected(
graph, graph,
calculateFileChanges(affectedFiles, allWorkspaceFiles) calculateFileChanges(affectedFiles, allWorkspaceFiles)

View File

@ -326,7 +326,7 @@ export async function generate(cwd: string, args: { [k: string]: any }) {
const ws = new Workspaces(workspaceRoot); const ws = new Workspaces(workspaceRoot);
const nxJson = readNxJson(); const nxJson = readNxJson();
const projectGraph = await createProjectGraphAsync(); const projectGraph = await createProjectGraphAsync({ exitOnError: true });
const projectsConfiguration = const projectsConfiguration =
readProjectsConfigurationFromProjectGraph(projectGraph); readProjectsConfigurationFromProjectGraph(projectGraph);

View File

@ -7,7 +7,7 @@ import { createProjectGraphAsync } from '../project-graph/project-graph';
import { pruneExternalNodes } from '../project-graph/operators'; import { pruneExternalNodes } from '../project-graph/operators';
export async function workspaceLint(): Promise<void> { export async function workspaceLint(): Promise<void> {
const graph = await createProjectGraphAsync(); const graph = await createProjectGraphAsync({ exitOnError: true });
const allWorkspaceFiles = graph.allWorkspaceFiles; const allWorkspaceFiles = graph.allWorkspaceFiles;
const projectGraph = pruneExternalNodes(graph); const projectGraph = pruneExternalNodes(graph);

View File

@ -44,7 +44,7 @@ export async function listHandler(args: ListArgs): Promise<void> {
return []; return [];
}); });
const projectGraph = await createProjectGraphAsync(); const projectGraph = await createProjectGraphAsync({ exitOnError: true });
const localPlugins = getLocalWorkspacePlugins( const localPlugins = getLocalWorkspacePlugins(
readProjectsConfigurationFromProjectGraph(projectGraph) readProjectsConfigurationFromProjectGraph(projectGraph)

View File

@ -72,7 +72,7 @@ export async function reportHandler() {
bodyLines.push('---------------------------------------'); bodyLines.push('---------------------------------------');
try { try {
const projectGraph = await createProjectGraphAsync(); const projectGraph = await createProjectGraphAsync({ exitOnError: true });
bodyLines.push('Local workspace plugins:'); bodyLines.push('Local workspace plugins:');
const plugins = getLocalWorkspacePlugins( const plugins = getLocalWorkspacePlugins(
readProjectsConfigurationFromProjectGraph(projectGraph) readProjectsConfigurationFromProjectGraph(projectGraph)

View File

@ -32,7 +32,7 @@ export async function runMany(
await connectToNxCloudUsingScan(nxArgs.scan); await connectToNxCloudUsingScan(nxArgs.scan);
const projectGraph = await createProjectGraphAsync(); const projectGraph = await createProjectGraphAsync({ exitOnError: true });
const projects = projectsToRun(nxArgs, projectGraph); const projects = projectsToRun(nxArgs, projectGraph);
await runCommand( await runCommand(

View File

@ -29,7 +29,7 @@ export async function runOne(
performance.measure('code-loading', 'init-local', 'command-execution-begins'); performance.measure('code-loading', 'init-local', 'command-execution-begins');
const nxJson = readNxJson(); const nxJson = readNxJson();
const projectGraph = await createProjectGraphAsync(); const projectGraph = await createProjectGraphAsync({ exitOnError: true });
const opts = parseRunOneOptions(cwd, args, { const opts = parseRunOneOptions(cwd, args, {
...readProjectsConfigurationFromProjectGraph(projectGraph), ...readProjectsConfigurationFromProjectGraph(projectGraph),

View File

@ -139,15 +139,18 @@ function daemonProcessException(message: string) {
if (log.length > 20) { if (log.length > 20) {
log = log.slice(log.length - 20); log = log.slice(log.length - 20);
} }
return new Error( const error = new Error(
[ [
message, message,
'',
'Messages from the log:', 'Messages from the log:',
...log, ...log,
'\n', '\n',
`More information: ${DAEMON_OUTPUT_LOG_FILE}`, `More information: ${DAEMON_OUTPUT_LOG_FILE}`,
].join('\n') ].join('\n')
); );
(error as any).internalDaemonError = true;
return error;
} catch (e) { } catch (e) {
return new Error(message); return new Error(message);
} }
@ -209,11 +212,13 @@ async function sendMessageToDaemon(message: {
socket.on('error', (err) => { socket.on('error', (err) => {
if (!err.message) { if (!err.message) {
return reject(err); return reject(daemonProcessException(err.toString()));
} }
if (err.message.startsWith('LOCK-FILES-CHANGED')) { if (err.message.startsWith('LOCK-FILES-CHANGED')) {
return sendMessageToDaemon(message).then(resolve, reject); return sendMessageToDaemon(message).then(resolve, reject);
} }
let error: any; let error: any;
if (err.message.startsWith('connect ENOENT')) { if (err.message.startsWith('connect ENOENT')) {
error = daemonProcessException('The Daemon Server is not running'); error = daemonProcessException('The Daemon Server is not running');
@ -226,8 +231,10 @@ async function sendMessageToDaemon(message: {
error = daemonProcessException( error = daemonProcessException(
`Unable to connect to the daemon process.` `Unable to connect to the daemon process.`
); );
} else {
error = daemonProcessException(err.toString());
} }
return reject(error || err); return reject(error);
}); });
socket.on('ready', () => { socket.on('ready', () => {

View File

@ -80,6 +80,22 @@ async function buildProjectGraphWithoutDaemon() {
return await buildProjectGraph(); return await buildProjectGraph();
} }
function handleProjectGraphError(opts: { exitOnError: boolean }, e) {
if (opts.exitOnError) {
const lines = e.message.split('\n');
output.error({
title: lines[0],
bodyLines: lines.slice(1),
});
if (process.env.NX_VERBOSE_LOGGING === 'true') {
console.error(e);
}
process.exit(1);
} else {
throw e;
}
}
/** /**
* Computes and returns a ProjectGraph. * Computes and returns a ProjectGraph.
* *
@ -101,15 +117,25 @@ async function buildProjectGraphWithoutDaemon() {
* Nx uses two layers of caching: the information about explicit dependencies stored on the disk and the information * Nx uses two layers of caching: the information about explicit dependencies stored on the disk and the information
* stored in the daemon process. To reset both run: `nx reset`. * stored in the daemon process. To reset both run: `nx reset`.
*/ */
export async function createProjectGraphAsync(): Promise<ProjectGraph> { export async function createProjectGraphAsync(
opts: { exitOnError: boolean } = { exitOnError: false }
): Promise<ProjectGraph> {
const nxJson = readNxJson(); const nxJson = readNxJson();
const daemon = new DaemonClient(nxJson); const daemon = new DaemonClient(nxJson);
if (!daemon.enabled()) { if (!daemon.enabled()) {
return await buildProjectGraphWithoutDaemon(); try {
return await buildProjectGraphWithoutDaemon();
} catch (e) {
handleProjectGraphError(opts, e);
}
} else { } else {
try { try {
return daemon.getProjectGraph(); return await daemon.getProjectGraph();
} catch (e) { } catch (e) {
if (!e.internalDaemonError) {
handleProjectGraphError(opts, e);
}
if (e.message.indexOf('inotify_add_watch') > -1) { if (e.message.indexOf('inotify_add_watch') > -1) {
// common errors with the daemon due to OS settings (cannot watch all the files available) // common errors with the daemon due to OS settings (cannot watch all the files available)
output.note({ output.note({