Skip to content

Commit 41b39e8

Browse files
committed
allowed ability to control breaking into exceptions
1 parent 8776804 commit 41b39e8

9 files changed

Lines changed: 486 additions & 430 deletions

File tree

package.json

Lines changed: 412 additions & 383 deletions
Large diffs are not rendered by default.

src/client/common/childProc.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@ export function sendCommand(commandLine: string, cwd: string, includeErrorAsResp
99

1010
child_process.exec(commandLine, { cwd: cwd }, (error, stdout, stderr) => {
1111
if (includeErrorAsResponse){
12-
return resolve(stdout.toString('utf-8') + '\n' + stderr.toString('utf-8'));
12+
return resolve(stdout + '\n' + stderr);
1313
}
1414

1515
var hasErrors = (error && error.message.length > 0) || (stderr && stderr.length > 0);
1616
if (hasErrors && (typeof stdout !== "string" || stdout.length === 0)) {
17-
var errorMsg = (error && error.message) ? error.message : (stderr && stderr.length > 0 ? stderr.toString("utf-8") : "");
17+
var errorMsg = (error && error.message) ? error.message : (stderr && stderr.length > 0 ? stderr + '' : "");
1818
return reject(errorMsg);
1919
}
2020

21-
resolve(stdout.toString('utf-8'));
21+
resolve(stdout + '');
2222
});
2323
});
2424
}

src/client/debugger/Common/Contracts.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ export class DebugOptions {
1616
public static get DebugStdLib(): string { return "DebugStdLib"; }
1717
public static get BreakOnSystemExitZero(): string { return "BreakOnSystemExitZero"; }
1818
}
19+
20+
export interface ExceptionHandling {
21+
ignore: string[];
22+
always: string[];
23+
unhandled: string[];
24+
}
25+
1926
export interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArguments {
2027
/** An absolute path to the program to debug. */
2128
program: string;
@@ -28,6 +35,7 @@ export interface LaunchRequestArguments extends DebugProtocol.LaunchRequestArgum
2835
cwd?: string;
2936
debugOptions?: string[];
3037
env?: Object;
38+
exceptionHandling?: ExceptionHandling
3139
}
3240
//
3341
// export interface LaunchDjangoRequestArguments extends LaunchRequestArguments {

src/client/debugger/Common/OnPortOpenedHandler.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export function WaitForPortToOpen(port: number, timeout: number): Promise<any> {
1717
return;
1818
}
1919

20-
var socket = net.connect(port, () => {
20+
var socket = net.connect({ port: port }, () => {
2121
if (timedOut) {
2222
return;
2323
}
@@ -26,7 +26,7 @@ export function WaitForPortToOpen(port: number, timeout: number): Promise<any> {
2626
socket.end();
2727
clearTimeout(handle);
2828
});
29-
socket.on("error", error=> {
29+
socket.on("error", error => {
3030
if (timedOut) {
3131
return;
3232
}

src/client/debugger/DebugServers/RemoteDebugServer.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export class RemoteDebugServer extends BaseDebugServer {
4444
var languageVersionRead = false;
4545
var portNumber = this.args.port;
4646
var debugCommandsAccepted = false;
47-
this.socket = net.connect(portNumber, () => {
47+
this.socket = net.connect({ port: portNumber }, () => {
4848
console.log('client connected');
4949
console.log(`Debug server started, listening on port ${portNumber}`);
5050
resolve({ port: portNumber });
@@ -90,7 +90,7 @@ export class RemoteDebugServer extends BaseDebugServer {
9090
that.stream.RollBackTransaction()
9191
return;
9292
}
93-
93+
9494
// If we are talking the same protocol but different version, reply with signature + version before bailing out
9595
// so that ptvsd has a chance to gracefully close the socket on its side.
9696
that.stream.EndTransaction();
@@ -180,17 +180,17 @@ export class RemoteDebugServer extends BaseDebugServer {
180180
}
181181
}
182182
});
183-
this.socket.on("close", d=> {
183+
this.socket.on("close", d => {
184184
var msg = `Debugger client closed, ${d}`;
185185
console.log(msg);
186186
that.emit("detach", d);
187187
});
188-
this.socket.on("timeout", d=> {
188+
this.socket.on("timeout", d => {
189189
var msg = `Debugger client timedout, ${d}`;
190190
that.debugSession.sendEvent(new OutputEvent(msg + "\n", "stderr"));
191191
console.log(msg);
192192
});
193-
this.socket.on("error", ex=> {
193+
this.socket.on("error", ex => {
194194
var exMessage = JSON.stringify(ex);
195195
var msg = `There was an error in starting the debug server. Error = ${exMessage}`;
196196
that.debugSession.sendEvent(new OutputEvent(msg + "\n", "stderr"));

src/client/debugger/Main.ts

Lines changed: 50 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,16 @@ export class PythonDebugger extends DebugSession {
7474
private InitializeEventHandlers() {
7575
this.pythonProcess.on("last", arg => this.onDetachDebugger());
7676
this.pythonProcess.on("threadExited", arg => this.onPythonThreadExited(arg));
77-
this.pythonProcess.on("moduleLoaded", arg=> this.onPythonModuleLoaded(arg));
78-
this.pythonProcess.on("threadCreated", arg=> this.onPythonThreadCreated(arg));
79-
this.pythonProcess.on("processLoaded", arg=> this.onPythonProcessLoaded(arg));
77+
this.pythonProcess.on("moduleLoaded", arg => this.onPythonModuleLoaded(arg));
78+
this.pythonProcess.on("threadCreated", arg => this.onPythonThreadCreated(arg));
79+
this.pythonProcess.on("processLoaded", arg => this.onPythonProcessLoaded(arg));
8080
this.pythonProcess.on("output", (pyThread, output) => this.onDebuggerOutput(pyThread, output));
8181
this.pythonProcess.on("exceptionRaised", (pyThread, ex) => this.onPythonException(pyThread, ex));
8282
this.pythonProcess.on("breakpointHit", (pyThread, breakpointId) => this.onBreakpointHit(pyThread, breakpointId));
8383
this.pythonProcess.on("stepCompleted", (pyThread) => this.onStepCompleted(pyThread));
8484
this.pythonProcess.on("detach", () => this.onDetachDebugger());
8585
this.pythonProcess.on("error", ex => this.sendEvent(new OutputEvent(ex, "stderr")));
86-
this.pythonProcess.on("asyncBreakCompleted", arg=> this.onPythonProcessPaused(arg));
86+
this.pythonProcess.on("asyncBreakCompleted", arg => this.onPythonProcessPaused(arg));
8787

8888
this.debugServer.on("detach", () => this.onDetachDebugger());
8989
}
@@ -138,7 +138,7 @@ export class PythonDebugger extends DebugSession {
138138
this.launchArgs = args;
139139
this.debugClient = CreateLaunchDebugClient(args, this);
140140

141-
this.debuggerLoaded = new Promise(resolve=> {
141+
this.debuggerLoaded = new Promise(resolve => {
142142
this.debuggerLoadedPromiseResolve = resolve;
143143
});
144144

@@ -149,12 +149,12 @@ export class PythonDebugger extends DebugSession {
149149
this.startDebugServer().then(dbgServer => {
150150
that.debugClient.LaunchApplicationToDebug(dbgServer).then(() => {
151151

152-
}, error=> {
152+
}, error => {
153153
this.sendEvent(new OutputEvent(error + "\n", "stderr"));
154154
this.sendErrorResponse(that.entryResponse, 2000, error);
155155
});
156156
});
157-
}, error=> {
157+
}, error => {
158158
this.sendEvent(new OutputEvent(error + "\n", "stderr"));
159159
this.sendErrorResponse(that.entryResponse, 2000, error);
160160
});
@@ -163,7 +163,7 @@ export class PythonDebugger extends DebugSession {
163163
this.attachArgs = args;
164164
this.debugClient = CreateAttachDebugClient(args, this);
165165

166-
this.debuggerLoaded = new Promise(resolve=> {
166+
this.debuggerLoaded = new Promise(resolve => {
167167
this.debuggerLoadedPromiseResolve = resolve;
168168
});
169169

@@ -174,7 +174,7 @@ export class PythonDebugger extends DebugSession {
174174
this.startDebugServer().then(dbgServer => {
175175
that.debugClient.LaunchApplicationToDebug(dbgServer);
176176
});
177-
}, error=> {
177+
}, error => {
178178
this.sendEvent(new OutputEvent(error + "\n", "stderr"));
179179
this.sendErrorResponse(that.entryResponse, 2000, error);
180180
});
@@ -218,19 +218,19 @@ export class PythonDebugger extends DebugSession {
218218

219219
var breakpoints: { verified: boolean, line: number }[] = [];
220220
var breakpointsToRemove = [];
221-
var linesToAdd = args.breakpoints.map(b=> b.line);
221+
var linesToAdd = args.breakpoints.map(b => b.line);
222222
var registeredBks = this.registeredBreakpointsByFileName.get(args.source.path);
223-
var linesToRemove = registeredBks.map(b=> b.LineNo).filter(oldLine=> linesToAdd.indexOf(oldLine) === -1);
224-
var linesToUpdate = registeredBks.map(b=> b.LineNo).filter(oldLine=> linesToAdd.indexOf(oldLine) >= 0);
225-
223+
var linesToRemove = registeredBks.map(b => b.LineNo).filter(oldLine => linesToAdd.indexOf(oldLine) === -1);
224+
var linesToUpdate = registeredBks.map(b => b.LineNo).filter(oldLine => linesToAdd.indexOf(oldLine) >= 0);
225+
226226
//Always add new breakpoints, don't re-enable previous breakpoints
227227
//Cuz sometimes some breakpoints get added too early (e.g. in django) and don't get registeredBks
228228
//and the response comes back indicating it wasn't set properly
229229
//However, at a later point in time, the program breaks at that point!!!
230-
var linesToAddPromises = args.breakpoints.map(bk=> {
231-
return new Promise(resolve=> {
230+
var linesToAddPromises = args.breakpoints.map(bk => {
231+
return new Promise(resolve => {
232232
var breakpoint: IPythonBreakpoint;
233-
var existingBreakpointsForThisLine = registeredBks.filter(registeredBk=> registeredBk.LineNo === bk.line);
233+
var existingBreakpointsForThisLine = registeredBks.filter(registeredBk => registeredBk.LineNo === bk.line);
234234
if (existingBreakpointsForThisLine.length > 0) {
235235
//We have an existing breakpoint for this line
236236
//just enable that
@@ -246,7 +246,7 @@ export class PythonDebugger extends DebugSession {
246246
breakpoints.push({ verified: true, line: bk.line });
247247
registeredBks.push(breakpoint);
248248
resolve();
249-
}, reason=> {
249+
}, reason => {
250250
this.registeredBreakpoints.set(breakpoint.Id, breakpoint);
251251
breakpoints.push({ verified: false, line: bk.line });
252252
registeredBks.push(breakpoint);
@@ -255,10 +255,10 @@ export class PythonDebugger extends DebugSession {
255255
});
256256
});
257257

258-
var linesToRemovePromises = linesToRemove.map(line=> {
259-
return new Promise(resolve=> {
258+
var linesToRemovePromises = linesToRemove.map(line => {
259+
return new Promise(resolve => {
260260
var registeredBks = this.registeredBreakpointsByFileName.get(args.source.path);
261-
var bk = registeredBks.filter(b=> b.LineNo === line)[0];
261+
var bk = registeredBks.filter(b => b.LineNo === line)[0];
262262
//Ok, we won't get a response back, so update the breakpoints list indicating this has been disabled
263263
bk.Enabled = false;
264264
this.pythonProcess.DisableBreakPoint(bk);
@@ -279,7 +279,7 @@ export class PythonDebugger extends DebugSession {
279279

280280
protected threadsRequest(response: DebugProtocol.ThreadsResponse): void {
281281
var threads = [];
282-
this.pythonProcess.Threads.forEach(t=> {
282+
this.pythonProcess.Threads.forEach(t => {
283283
threads.push(new Thread(t.Id, t.Name));
284284
});
285285

@@ -367,8 +367,8 @@ export class PythonDebugger extends DebugSession {
367367
return this.sendResponse(response);
368368
}
369369

370-
this.pythonProcess.ExecuteText(args.expression, PythonEvaluationResultReprKind.Normal, frame).then(result=> {
371-
let variablesReference = 0;
370+
this.pythonProcess.ExecuteText(args.expression, PythonEvaluationResultReprKind.Normal, frame).then(result => {
371+
let variablesReference = 0;
372372
//If this value can be expanded, then create a vars ref for user to expand it
373373
if (result.IsExpandable) {
374374
const parentVariable: IDebugVariable = {
@@ -419,7 +419,7 @@ export class PythonDebugger extends DebugSession {
419419

420420
if (varRef.evaluateChildren !== true) {
421421
let variables = [];
422-
varRef.variables.forEach(variable=> {
422+
varRef.variables.forEach(variable => {
423423
let variablesReference = 0;
424424
//If this value can be expanded, then create a vars ref for user to expand it
425425
if (variable.IsExpandable) {
@@ -443,12 +443,12 @@ export class PythonDebugger extends DebugSession {
443443

444444
return this.sendResponse(response);
445445
}
446-
446+
447447
//Ok, we need to evaluate the children of the current variable
448448
var variables = [];
449-
var promises = varRef.variables.map(variable=> {
450-
return variable.Process.EnumChildren(variable.Expression, variable.Frame, CHILD_ENUMEARATION_TIMEOUT).then(children=> {
451-
children.forEach(child=> {
449+
var promises = varRef.variables.map(variable => {
450+
return variable.Process.EnumChildren(variable.Expression, variable.Frame, CHILD_ENUMEARATION_TIMEOUT).then(children => {
451+
children.forEach(child => {
452452
let variablesReference = 0;
453453
//If this value can be expanded, then create a vars ref for user to expand it
454454
if (child.IsExpandable) {
@@ -465,7 +465,7 @@ export class PythonDebugger extends DebugSession {
465465
variablesReference: variablesReference
466466
});
467467
});
468-
}, error=> {
468+
}, error => {
469469
this.sendErrorResponse(response, 2001, error);
470470
});
471471
});
@@ -491,7 +491,27 @@ export class PythonDebugger extends DebugSession {
491491
if (args.filters.indexOf("all") >= 0) {
492492
mode = enum_EXCEPTION_STATE.BREAK_MODE_ALWAYS;
493493
}
494-
this.pythonProcess.SendExceptionInfo(mode, null);
494+
var exToIgnore = null;
495+
var exceptionHandling = this.launchArgs.exceptionHandling;
496+
if (exceptionHandling) {
497+
exToIgnore = new Map<string, enum_EXCEPTION_STATE>();
498+
if (Array.isArray(exceptionHandling.ignore)) {
499+
exceptionHandling.ignore.forEach(exType => {
500+
exToIgnore.set(exType, enum_EXCEPTION_STATE.BREAK_MODE_NEVER);
501+
});
502+
}
503+
if (Array.isArray(exceptionHandling.always)) {
504+
exceptionHandling.always.forEach(exType => {
505+
exToIgnore.set(exType, enum_EXCEPTION_STATE.BREAK_MODE_ALWAYS);
506+
});
507+
}
508+
if (Array.isArray(exceptionHandling.unhandled)) {
509+
exceptionHandling.unhandled.forEach(exType => {
510+
exToIgnore.set(exType, enum_EXCEPTION_STATE.BREAK_MODE_UNHANDLED);
511+
});
512+
}
513+
}
514+
this.pythonProcess.SendExceptionInfo(mode, exToIgnore);
495515
this.sendResponse(response);
496516
});
497517
}

src/client/debugger/PythonProcess.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,10 +201,10 @@ export class PythonProcess extends EventEmitter implements IPythonProcess {
201201
}
202202
else {
203203
this.stream.WriteInt32(breakOn.size);
204-
for (var key in breakOn.keys()) {
205-
this.stream.WriteInt32(breakOn.get(key));
204+
breakOn.forEach((value,key)=>{
205+
this.stream.WriteInt32(value);
206206
this.stream.WriteString(key);
207-
}
207+
});
208208
}
209209
}
210210

src/client/providers/jediProxy.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@ function killProcess() {
165165

166166
function handleError(source: string, errorMessage: string) {
167167
logger.error(source + ' jediProxy', `Error (${source}) ${errorMessage}`);
168-
vscode.window.showErrorMessage(`There was an error in the python extension. Error ${errorMessage}`);
169168
}
170169

171170
function spawnProcess(dir: string) {

src/server/linters/pylint.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,15 @@ export class Linter {
8585
return new Promise<Diagnostic[]>((resolve, reject) => {
8686
var dir = path.dirname(filePath);
8787
//var cmd: string = `${PYLINT_COMMANDLINE} ${filePath}`;
88-
exec(cmd,{cwd:dir}, (error: Error, stdout: Buffer, stderr: Buffer) => {
89-
var outputLines = (stdout || "").toString('utf-8').split(/\r?\n/g);
88+
exec(cmd,{cwd:dir}, (error: Error, stdout: string, stderr: string) => {
89+
var outputLines = (stdout || "").split(/\r?\n/g);
9090
if (outputLines.length === 0 || outputLines[0] === ""){
9191
var errorMessages = [];
9292
if (error && error.message){
9393
errorMessages.push(`Error Message (${error.name}) : ${error.message}`);
9494
}
9595
if (stderr && stderr.length > 0){
96-
errorMessages.push(stderr.toString('utf-8'));
96+
errorMessages.push(stderr + '');
9797
}
9898
if (errorMessages.length === 0){
9999
return resolve([])

0 commit comments

Comments
 (0)