Skip to content

Commit ab25c41

Browse files
committed
handle invalid pythonPath when debugging #229
1 parent b56b78e commit ab25c41

6 files changed

Lines changed: 49 additions & 9 deletions

File tree

src/client/debugger/DebugClients/DebugClient.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export abstract class DebugClient {
2323
public Stop() {
2424
}
2525

26-
public LaunchApplicationToDebug(dbgServer: IDebugServer): Promise<any> {
26+
public LaunchApplicationToDebug(dbgServer: IDebugServer, processErrored: (error: any) => void): Promise<any> {
2727
return Promise.resolve();
2828
}
2929
}

src/client/debugger/DebugClients/LocalDebugClient.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export class LocalDebugClient extends DebugClient {
6464
this.debugSession.sendEvent(new OutputEvent(context + (context.length > 0 ? ": " : "") + errorMsg + "\n", "stderr"));
6565
}
6666
}
67-
public LaunchApplicationToDebug(dbgServer: IDebugServer): Promise<any> {
67+
public LaunchApplicationToDebug(dbgServer: IDebugServer, processErrored: (error: any) => void): Promise<any> {
6868
return new Promise<any>((resolve, reject) => {
6969
let fileDir = path.dirname(this.args.program);
7070
let processCwd = fileDir;
@@ -113,6 +113,10 @@ export class LocalDebugClient extends DebugClient {
113113
if (!this.debugServer && this.debugServer.IsRunning) {
114114
return;
115115
}
116+
if (!this.debugServer.IsRunning && typeof (error) === 'object' && error !== null) {
117+
//return processErrored(error);
118+
return reject(error);
119+
}
116120
this.displayError(error, "pyProc.error");
117121
});
118122
this.pyProc.stderr.setEncoding("utf8");
@@ -126,8 +130,12 @@ export class LocalDebugClient extends DebugClient {
126130
this.pyProc.stdout.on("data", d => {
127131
// This is necessary so we read the stdout of the python process
128132
// Else it just keep building up (related to issue #203 and #52)
133+
let x = 0;
129134
})
130-
resolve();
135+
// Here we wait for the application to connect to the socket server
136+
// Only once connected do we know that the application has successfully launched
137+
//resolve();
138+
this.debugServer.ClientConnected.then(resolve);
131139
});
132140
}
133141
protected buildLauncherArguments(): string[] {

src/client/debugger/DebugServers/BaseDebugServer.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ export abstract class BaseDebugServer extends EventEmitter {
1313
public get IsRunning(): boolean {
1414
return this.isRunning;
1515
}
16-
16+
public get ClientConnected(): Promise<boolean> {
17+
return Promise.resolve(true);
18+
}
1719
constructor(debugSession: DebugSession, pythonProcess: IPythonProcess) {
1820
super();
1921
this.debugSession = debugSession;

src/client/debugger/DebugServers/LocalDebugServer.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ export class LocalDebugServer extends BaseDebugServer {
1010

1111
constructor(debugSession: DebugSession, pythonProcess: IPythonProcess) {
1212
super(debugSession, pythonProcess);
13+
this.clientConnected = new Promise<Boolean>(resolve => {
14+
this.clientConnectedResolve = resolve;
15+
});
16+
}
17+
private clientConnected: Promise<Boolean>;
18+
private clientConnectedResolve: (value?: Boolean | PromiseLike<Boolean>) => void;
19+
public get ClientConnected(): Promise<boolean> {
20+
return this.clientConnected;
1321
}
1422

1523
public Stop() {
@@ -28,6 +36,11 @@ export class LocalDebugServer extends BaseDebugServer {
2836
// "connection" listener
2937
let connected = false;
3038
c.on("data", (buffer: Buffer) => {
39+
if (that.clientConnectedResolve) {
40+
// The debug client has connected to the debug server
41+
that.clientConnectedResolve(true);
42+
that.clientConnectedResolve = null;
43+
}
3144
if (!connected) {
3245
connected = that.pythonProcess.Connect(buffer, c, false);
3346
}

src/client/debugger/Main.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ export class PythonDebugger extends DebugSession {
8888
}
8989
if (this.pythonProcess) {
9090
this.pythonProcess.Kill();
91+
this.pythonProcess = null;
9192
}
9293
}
9394
private InitializeEventHandlers() {
@@ -183,12 +184,28 @@ export class PythonDebugger extends DebugSession {
183184
let that = this;
184185

185186
this.startDebugServer().then(dbgServer => {
186-
return that.debugClient.LaunchApplicationToDebug(dbgServer);
187+
return that.debugClient.LaunchApplicationToDebug(dbgServer, that.unhandledProcessError.bind(that));
187188
}).catch(error => {
188189
this.sendEvent(new OutputEvent(error + "\n", "stderr"));
189-
this.sendErrorResponse(that.entryResponse, 2000, error);
190+
response.success = false;
191+
let errorMsg = typeof error === "string" ? error : ((error.message && error.message.length > 0) ? error.message : error + '');
192+
if ((<any>error).code === 'ENOENT' || (<any>error).code === 127) {
193+
errorMsg = `Failed to launch the Python Process, please validate the path '${this.launchArgs.pythonPath}'`;
194+
}
195+
this.sendErrorResponse(response, 200, errorMsg);
190196
});
191197
}
198+
protected unhandledProcessError(error: any) {
199+
if (!error) { return; }
200+
let errorMsg = typeof error === "string" ? error : ((error.message && error.message.length > 0) ? error.message : "");
201+
if ((<any>error).code === 'ENOENT' || (<any>error).code === 127) {
202+
errorMsg = `Failed to launch the Python Process, please validate the path '${this.launchArgs.pythonPath}'`;
203+
}
204+
if (errorMsg.length > 0) {
205+
this.sendEvent(new OutputEvent(errorMsg + "\n", "stderr"));
206+
}
207+
this.sendEvent(new TerminatedEvent());
208+
}
192209
protected attachRequest(response: DebugProtocol.AttachResponse, args: AttachRequestArguments) {
193210
this.sendEvent(new TelemetryEvent(telemetryContracts.Debugger.Attach));
194211
this.attachArgs = args;
@@ -199,7 +216,7 @@ export class PythonDebugger extends DebugSession {
199216
this.canStartDebugger().then(() => {
200217
return this.startDebugServer();
201218
}).then(dbgServer => {
202-
return that.debugClient.LaunchApplicationToDebug(dbgServer);
219+
return that.debugClient.LaunchApplicationToDebug(dbgServer, () => { });
203220
}).catch(error => {
204221
this.sendEvent(new OutputEvent(error + "\n", "stderr"));
205222
this.sendErrorResponse(that.entryResponse, 2000, error);

src/client/debugger/PythonProcess.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export class PythonProcess extends EventEmitter implements IPythonProcess {
6060
}
6161

6262
public Kill() {
63-
if (!this.isRemoteProcess && typeof this.pid === "number") {
63+
if (!this.isRemoteProcess && this.pid && typeof this.pid === "number") {
6464
try {
6565
let kill = require("tree-kill");
6666
kill(this.pid);
@@ -81,7 +81,7 @@ export class PythonProcess extends EventEmitter implements IPythonProcess {
8181
private guidRead: boolean;
8282
private statusRead: boolean;
8383
private pidRead: boolean;
84-
private pid: number = 0;
84+
private pid: number;
8585
private isRemoteProcess: Boolean;
8686
public Connect(buffer: Buffer, socket: net.Socket, isRemoteProcess: boolean = false): boolean {
8787
this.isRemoteProcess = isRemoteProcess;

0 commit comments

Comments
 (0)