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 check-commit &&
npx nx-cloud record yarn check-lock-files &&
npx nx-cloud record yarn nx workspace-lint &&
npx nx-cloud record yarn depcheck) &
pids+=($!)
(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) &
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+=($!)
yarn nx affected --target=test --base=$NX_BASE --head=$NX_HEAD --parallel=1 &
pids+=($!)
for pid in "${pids[@]}"; do
wait "$pid"
done
- run:
name: Stop All Running Agents for This CI Run
command: npx nx-cloud stop-all-agents
when: always
# -------------------------
# JOBS: Main-MacOS
# -------------------------
@ -237,10 +233,6 @@ jobs:
echo "Skipping E2E tests";
fi
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)

View File

@ -901,7 +901,7 @@ Convert an Nx Generator into an Angular Devkit Schematic.
### createProjectGraphAsync
**createProjectGraphAsync**(): `Promise`<[`ProjectGraph`](../../devkit/index#projectgraph)\>
**createProjectGraphAsync**(`opts?`): `Promise`<[`ProjectGraph`](../../devkit/index#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
stored in the daemon process. To reset both run: `nx reset`.
#### Parameters
| Name | Type |
| :----------------- | :-------- |
| `opts` | `Object` |
| `opts.exitOnError` | `boolean` |
#### Returns
`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);
const projectGraph = await createProjectGraphAsync();
const projectGraph = await createProjectGraphAsync({ exitOnError: true });
const projects = projectsToRun(nxArgs, projectGraph);
try {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -80,6 +80,22 @@ async function buildProjectGraphWithoutDaemon() {
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.
*
@ -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
* 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 daemon = new DaemonClient(nxJson);
if (!daemon.enabled()) {
try {
return await buildProjectGraphWithoutDaemon();
} catch (e) {
handleProjectGraphError(opts, e);
}
} else {
try {
return daemon.getProjectGraph();
return await daemon.getProjectGraph();
} catch (e) {
if (!e.internalDaemonError) {
handleProjectGraphError(opts, e);
}
if (e.message.indexOf('inotify_add_watch') > -1) {
// common errors with the daemon due to OS settings (cannot watch all the files available)
output.note({