Skip to content

Commit fa45d29

Browse files
committed
add options for handling errors encountered
1 parent b7fee7c commit fa45d29

File tree

5 files changed

+103
-2
lines changed

5 files changed

+103
-2
lines changed

package.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,27 @@
139139
"tags": [
140140
"experimental"
141141
]
142+
},
143+
"debugpy.onErrors": {
144+
"default": "debugAnyway",
145+
"description": "%debugpy.onErrors.description%",
146+
"scope": "resource",
147+
"type": "string",
148+
"enum": [
149+
"debugAnyway",
150+
"showErrors",
151+
"abort",
152+
"prompt"
153+
],
154+
"enumDescriptions": [
155+
"Continue debugging.",
156+
"Show errors and stop debugging.",
157+
"Stop debugging.",
158+
"Let the user choose the action."
159+
],
160+
"tags": [
161+
"experimental"
162+
]
142163
}
143164
},
144165
"title": "Python Debugger",

package.nls.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
"debugpy.command.reportIssue.title": "Report Issue...",
66
"debugpy.command.viewOutput.title": "Show Output",
77
"debugpy.debugJustMyCode.description": "When debugging only step through user-written code. Disable this to allow stepping into library code.",
8-
"debugpy.showPythonInlineValues.description": "Whether to display inline values in the editor while debugging."
8+
"debugpy.showPythonInlineValues.description": "Whether to display inline values in the editor while debugging.",
9+
"debugpy.onErrors.description": "Controls what to do when errors are encountered before debugging."
910
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
'use strict';
5+
6+
import { DiagnosticSeverity, l10n, languages, MessageOptions, window } from 'vscode';
7+
import { getConfiguration } from './vscodeapi';
8+
9+
export async function resolveOnErrorsAction(): Promise<OnErrorsActions> {
10+
const onErrors = getConfiguration('debugpy').get<string>('onErrors', OnErrorsActions.debugAnyway);
11+
if (onErrors === OnErrorsActions.debugAnyway) {
12+
return OnErrorsActions.debugAnyway;
13+
}
14+
15+
const hasErrors = languages
16+
.getDiagnostics()
17+
.map((d) => {
18+
return d[1];
19+
})
20+
.flat()
21+
.some((d) => {
22+
return d.severity === DiagnosticSeverity.Error;
23+
});
24+
if (!hasErrors) {
25+
return OnErrorsActions.debugAnyway;
26+
}
27+
28+
if (onErrors === OnErrorsActions.prompt) {
29+
const message = l10n.t('Error exists before debugging.');
30+
const options: MessageOptions = { modal: true };
31+
const actions = [
32+
{ title: 'Debug Anyway', id: OnErrorsActions.debugAnyway },
33+
{ title: 'Show Errors', id: OnErrorsActions.showErrors },
34+
{ title: 'Abort', id: OnErrorsActions.abort, isCloseAffordance: true },
35+
];
36+
37+
const result = await window.showWarningMessage(message, options, ...actions);
38+
return (result?.id as OnErrorsActions) ?? OnErrorsActions.abort;
39+
}
40+
41+
return onErrors as OnErrorsActions;
42+
}
43+
44+
export enum OnErrorsActions {
45+
debugAnyway = 'debugAnyway',
46+
showErrors = 'showErrors',
47+
abort = 'abort',
48+
prompt = 'prompt',
49+
}

src/extension/debugger/configuration/debugConfigurationService.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Licensed under the MIT License.
33

44
import { cloneDeep } from 'lodash';
5-
import { CancellationToken, DebugConfiguration, QuickPickItem, WorkspaceFolder } from 'vscode';
5+
import { CancellationToken, commands, DebugConfiguration, QuickPickItem, WorkspaceFolder } from 'vscode';
66
import { DebugConfigStrings } from '../../common/utils/localize';
77
import { IMultiStepInputFactory, InputStep, IQuickPickParameters, MultiStepInput } from '../../common/multiStepInput';
88
import { AttachRequestArguments, DebugConfigurationArguments, LaunchRequestArguments } from '../../types';
@@ -17,6 +17,7 @@ import { buildPyramidLaunchConfiguration } from './providers/pyramidLaunch';
1717
import { buildRemoteAttachConfiguration } from './providers/remoteAttach';
1818
import { IDebugConfigurationResolver } from './types';
1919
import { buildFileWithArgsLaunchDebugConfiguration } from './providers/fileLaunchWithArgs';
20+
import { OnErrorsActions, resolveOnErrorsAction } from '../../common/onErrorsAction';
2021

2122
export class PythonDebugConfigurationService implements IDebugConfigurationService {
2223
private cacheDebugConfig: DebugConfiguration | undefined = undefined;
@@ -48,6 +49,15 @@ export class PythonDebugConfigurationService implements IDebugConfigurationServi
4849
debugConfiguration: DebugConfiguration,
4950
token?: CancellationToken,
5051
): Promise<DebugConfiguration | undefined> {
52+
const action = await resolveOnErrorsAction();
53+
switch (action) {
54+
case OnErrorsActions.showErrors:
55+
await commands.executeCommand('workbench.panel.markers.view.focus');
56+
return undefined;
57+
58+
case OnErrorsActions.abort:
59+
return undefined;
60+
}
5161
if (debugConfiguration.request === 'attach') {
5262
return this.attachResolver.resolveDebugConfiguration(
5363
folder,

src/extension/extensionInit.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
'use strict';
55

66
import {
7+
commands,
78
ConfigurationChangeEvent,
89
debug,
910
DebugConfigurationProviderTriggerKind,
@@ -54,6 +55,7 @@ import { registerHexDebugVisualizationTreeProvider } from './debugger/visualizer
5455
import { PythonInlineValueProvider } from './debugger/inlineValue/pythonInlineValueProvider';
5556
import { traceLog } from './common/log/logging';
5657
import { registerNoConfigDebug } from './noConfigDebugInit';
58+
import { OnErrorsActions, resolveOnErrorsAction } from './common/onErrorsAction';
5759

5860
export async function registerDebugger(context: IExtensionContext): Promise<IExtensionApi> {
5961
const childProcessAttachService = new ChildProcessAttachService();
@@ -87,6 +89,15 @@ export async function registerDebugger(context: IExtensionContext): Promise<IExt
8789

8890
context.subscriptions.push(
8991
registerCommand(Commands.Debug_In_Terminal, async (file?: Uri) => {
92+
const action = await resolveOnErrorsAction();
93+
switch (action) {
94+
case OnErrorsActions.showErrors:
95+
await commands.executeCommand('workbench.panel.markers.view.focus');
96+
return;
97+
98+
case OnErrorsActions.abort:
99+
return;
100+
}
90101
traceLog("Debugging using the editor button 'Debug in terminal'");
91102
sendTelemetryEvent(EventName.DEBUG_IN_TERMINAL_BUTTON);
92103
const interpreter = await getInterpreterDetails(file);
@@ -101,6 +112,15 @@ export async function registerDebugger(context: IExtensionContext): Promise<IExt
101112

102113
context.subscriptions.push(
103114
registerCommand(Commands.Debug_Using_Launch_Config, async (file?: Uri) => {
115+
const action = await resolveOnErrorsAction();
116+
switch (action) {
117+
case OnErrorsActions.showErrors:
118+
await commands.executeCommand('workbench.panel.markers.view.focus');
119+
return;
120+
121+
case OnErrorsActions.abort:
122+
return;
123+
}
104124
traceLog("Debugging using the editor button 'Debug using the launch.json'");
105125
sendTelemetryEvent(EventName.DEBUG_USING_LAUNCH_CONFIG_BUTTON);
106126
const interpreter = await getInterpreterDetails(file);

0 commit comments

Comments
 (0)