diff --git a/nx-dev/nx-dev/next-env.d.ts b/nx-dev/nx-dev/next-env.d.ts
index 9bc3dd46b9..4f11a03dc6 100644
--- a/nx-dev/nx-dev/next-env.d.ts
+++ b/nx-dev/nx-dev/next-env.d.ts
@@ -1,5 +1,4 @@
///
-///
///
// NOTE: This file should not be edited
diff --git a/package.json b/package.json
index 956d5a5289..ff72ba6301 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@nrwl/nx-source",
- "version": "13.3.0-beta.22",
+ "version": "13.3.0-beta.24",
"description": "Smart, Extensible Build Framework",
"homepage": "https://nx.dev",
"private": true,
diff --git a/packages/workspace/src/core/project-graph/daemon/client/client.ts b/packages/workspace/src/core/project-graph/daemon/client/client.ts
index 6161f40103..39d762ed1f 100644
--- a/packages/workspace/src/core/project-graph/daemon/client/client.ts
+++ b/packages/workspace/src/core/project-graph/daemon/client/client.ts
@@ -1,6 +1,6 @@
import { logger, ProjectGraph } from '@nrwl/devkit';
import { ChildProcess, spawn, spawnSync } from 'child_process';
-import { existsSync, openSync } from 'fs';
+import { existsSync, openSync, readFileSync } from 'fs';
import { connect } from 'net';
import { performance } from 'perf_hooks';
import {
@@ -13,6 +13,7 @@ import {
killSocketOrPath,
} from '../socket-utils';
import { DAEMON_OUTPUT_LOG_FILE } from '../tmp-dir';
+import { output } from '../../../../utilities/output';
export async function startInBackground(): Promise {
await safelyCleanUpExistingProcess();
@@ -37,17 +38,45 @@ export async function startInBackground(): Promise {
/**
* Ensure the server is actually available to connect to via IPC before resolving
*/
+ let attempts = 0;
return new Promise((resolve) => {
const id = setInterval(async () => {
if (await isServerAvailable()) {
clearInterval(id);
resolve(backgroundProcess.pid);
+ } else if (attempts > 200) {
+ // daemon fails to start, the process probably exited
+ // we print the logs and exit the client
+ throw daemonProcessException(
+ 'Failed to start the Nx Daemon process.'
+ );
+ } else {
+ attempts++;
}
- }, 500);
+ }, 10);
});
} catch (err) {
- logger.error(err);
- process.exit(1);
+ throw err;
+ }
+}
+
+function daemonProcessException(message: string) {
+ try {
+ let log = readFileSync(DAEMON_OUTPUT_LOG_FILE).toString().split('\n');
+ if (log.length > 20) {
+ log = log.slice(log.length - 20);
+ }
+ return new Error(
+ [
+ message,
+ 'Messages from the log:',
+ ...log,
+ '\n',
+ `More information: ${DAEMON_OUTPUT_LOG_FILE}`,
+ ].join('\n')
+ );
+ } catch (e) {
+ return new Error(message);
}
}
@@ -71,7 +100,7 @@ export function stop(): void {
/**
* As noted in the comments above the createServer() call, in order to reliably (meaning it works
- * cross-platform) check whether or not the server is availabe to request a project graph from we
+ * cross-platform) check whether the server is available to request a project graph from we
* need to actually attempt connecting to it.
*
* Because of the behavior of named pipes on Windows, we cannot simply treat them as a file and
@@ -109,18 +138,22 @@ export async function getProjectGraphFromServer(): Promise {
const socket = connect(FULL_OS_SOCKET_PATH);
socket.on('error', (err) => {
- let errorMessage: string | undefined;
+ let error: any;
if (err.message.startsWith('connect ENOENT')) {
- errorMessage = 'Error: The Daemon Server is not running';
+ error = daemonProcessException('The Daemon Server is not running');
}
if (err.message.startsWith('connect ECONNREFUSED')) {
- // If somehow the file descriptor had not been released during a previous shut down.
- if (existsSync(FULL_OS_SOCKET_PATH)) {
- errorMessage = `Error: A server instance had not been fully shut down. Please try running the command again.`;
- killSocketOrPath();
- }
+ error = daemonProcessException(
+ `A server instance had not been fully shut down. Please try running the command again.`
+ );
+ killSocketOrPath();
}
- return reject(new Error(errorMessage) || err);
+ if (err.message.startsWith('read ECONNRESET')) {
+ error = daemonProcessException(
+ `Unable to connect to the daemon process.`
+ );
+ }
+ return reject(error || err);
});
/**
diff --git a/packages/workspace/src/core/project-graph/daemon/server/server.ts b/packages/workspace/src/core/project-graph/daemon/server/server.ts
index 0fbc85ca47..42de81b9ba 100644
--- a/packages/workspace/src/core/project-graph/daemon/server/server.ts
+++ b/packages/workspace/src/core/project-graph/daemon/server/server.ts
@@ -268,21 +268,30 @@ export async function startServer(): Promise {
if (!isWindows) {
killSocketOrPath();
}
- return new Promise((resolve) => {
- server.listen(FULL_OS_SOCKET_PATH, async () => {
- serverLogger.log(`Started listening on: ${FULL_OS_SOCKET_PATH}`);
- // this triggers the storage of the lock file hash
- lockFileChanged();
+ return new Promise((resolve, reject) => {
+ try {
+ server.listen(FULL_OS_SOCKET_PATH, async () => {
+ try {
+ serverLogger.log(`Started listening on: ${FULL_OS_SOCKET_PATH}`);
+ // this triggers the storage of the lock file hash
+ lockFileChanged();
- if (!watcherSubscription) {
- watcherSubscription = await subscribeToWorkspaceChanges(
- handleWorkspaceChanges
- );
- serverLogger.watcherLog(`Subscribed to changes within: ${appRootPath}`);
- }
-
- return resolve(server);
- });
+ if (!watcherSubscription) {
+ watcherSubscription = await subscribeToWorkspaceChanges(
+ handleWorkspaceChanges
+ );
+ serverLogger.watcherLog(
+ `Subscribed to changes within: ${appRootPath}`
+ );
+ }
+ return resolve(server);
+ } catch (err) {
+ reject(err);
+ }
+ });
+ } catch (err) {
+ reject(err);
+ }
});
}
diff --git a/packages/workspace/src/core/project-graph/daemon/server/start.ts b/packages/workspace/src/core/project-graph/daemon/server/start.ts
index 38013a0f16..7a351e9d4a 100644
--- a/packages/workspace/src/core/project-graph/daemon/server/start.ts
+++ b/packages/workspace/src/core/project-graph/daemon/server/start.ts
@@ -1,10 +1,12 @@
import { logger } from '@nrwl/devkit';
import { startServer } from './server';
+import * as process from 'process';
(async () => {
try {
await startServer();
} catch (err) {
logger.error(err);
+ process.exit(1);
}
})();