Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve suggestion when server-forever is unable to use the port #9288

Merged
merged 1 commit into from
Nov 5, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 54 additions & 9 deletions scopes/harmony/bit/server-forever.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import net from 'net';
import crypto from 'crypto';
import { execSync } from 'child_process';
import { spawn } from '@lydell/node-pty';

export function spawnPTY() {
Expand Down Expand Up @@ -79,15 +80,18 @@ export function spawnPTY() {

server.on('error', (err: any) => {
if (err.code === 'EADDRINUSE') {
console.error(`Error: Port ${PORT} is already in use.`);
console.error(`This port is assigned based on the workspace path: '${process.cwd()}'`);
console.error(`This means another instance may already be running in this workspace.`);
console.error(`\nTo resolve this issue:`);
console.error(`- If another instance is running, please stop it before starting a new one.`);
console.error(`- If no other instance is running, the port may be occupied by another application.`);
console.error(
` You can override the default port by setting the 'BIT_CLI_SERVER_SOCKET_PORT' environment variable.`
);
const pid = getPidByPort(PORT);
const usedByPid = pid ? ` (used by PID ${pid})` : '';
const killCmd = pid ? `\nAlternatively, you can kill the process by running "kill ${pid}".` : '';
console.error(`Error: Port ${PORT} is already in use${usedByPid}.
This port is assigned based on the workspace path: '${process.cwd()}'
This means another instance may already be running in this workspace.
\nTo resolve this issue:
- If another instance is running, please stop it before starting a new one.
If a vscode is open on this workspace, it might be running the server. Close it.${killCmd}
- If no other instance is running, the port may be occupied by another application.
You can override the default port by setting the 'BIT_CLI_SERVER_SOCKET_PORT' environment variable.
`);
process.exit(1); // Exit the process with an error code
} else {
console.error('Server encountered an error:', err);
Expand Down Expand Up @@ -140,3 +144,44 @@ export function getPortFromPath(path: string): number {

return port;
}

function getPidByPort(port: number): string | null {
const platform = process.platform;
try {
if (platform === 'darwin' || platform === 'linux') {
// For macOS and Linux
const cmd = `lsof -iTCP:${port} -sTCP:LISTEN -n -P`;
const stdout = execSync(cmd).toString();
const lines = stdout.trim().split('\n');

if (lines.length > 1) {
// Skip the header line and parse the first result
const columns = lines[1].split(/\s+/);
const pid = columns[1];
return pid;
}
} else if (platform === 'win32') {
// For Windows
const cmd = `netstat -ano -p tcp`;
const stdout = execSync(cmd).toString();
const lines = stdout.trim().split('\n');

for (const line of lines) {
if (line.trim().startsWith('TCP')) {
const columns = line.trim().split(/\s+/);
const localAddress = columns[1];
const pid = columns[4];

if (localAddress.endsWith(`:${port}`)) {
return pid;
}
}
}
} else {
console.error('Unsupported platform:', platform);
}
} catch (error: any) {
console.error('Error executing command:', error.message);
}
return null;
}