Add a troubleshooting page for the frequently asked errors (#341)
* Add a troubleshooting page for the frequently asked errors * Update the wrong link and remove the unnecessary separator * Update Troubleshooting.md * Make tslint happy * Refine the words per review * Add the missing items parameter for showErrorMessage function * Log the troubleshooting usage * Add a reference in README to link to troubleshooting page * Update the fix steps for illegal request type error * Refine the description words for differnt errors * Add jdk troubleshooting item * Add a link to submit an issue * Add compilation as a try step for ClassNotFoundException * Add the missing license header * Resolve the review comments for troubleshooting doc * Extract dup code to a helper function * Merge activation event to usage data * Refactor showMessage utility method * Add opn to dependency list * update package-lock.json
This commit is contained in:
parent
205e38797a
commit
0e86ed2cc7
|
@ -91,6 +91,9 @@ Please also check the documentation of [Language Support for Java by Red Hat](ht
|
|||
- `java.debug.settings.maxStringLength`: the maximum length of string displayed in "Variables" or "Debug Console" viewlet, the string longer than this length will be trimmed, defaults to `0` which means no trim is performed.
|
||||
- `java.debug.settings.enableHotCodeReplace`: enable hot code replace for Java code. Make sure the auto build is not disabled for [VSCode Java](https://github.com/redhat-developer/vscode-java). See the [wiki page](https://github.com/Microsoft/vscode-java-debug/wiki/Hot-Code-Replace) for more information about usages and limitations.
|
||||
|
||||
## Troubleshooting
|
||||
Reference the [troubleshooting guide](https://github.com/Microsoft/vscode-java-debug/blob/master/Troubleshooting.md) for common errors.
|
||||
|
||||
## Feedback and Questions
|
||||
You can find the full list of issues at [Issue Tracker](https://github.com/Microsoft/vscode-java-debug/issues). You can submit a [bug or feature suggestion](https://github.com/Microsoft/vscode-java-debug/issues/new), and participate community driven [](https://gitter.im/Microsoft/vscode-java-debug)
|
||||
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
# Troubleshooting
|
||||
|
||||
This document provides the information needed to troubleshoot common errors of Debugger for Java (the debugger). If it does not cover the problem you are seeing, please [log an issue](https://github.com/Microsoft/vscode-java-debug/issues) instead.
|
||||
|
||||
## Java Language Support extension fails to start.
|
||||
The debugger works with [Language Support for Java(TM) by Red Hat](https://marketplace.visualstudio.com/items?itemName=redhat.java) (the language server) for source mapping and project support. If the language server fails to start, the debugger will not work as expected. Here is a simple way to check whether the language server is started. Open a .java or a Java project folder in VS Code, and then check the icon at the right side of the status bar. You should see the 👍 icon if the language server is loaded correctly.
|
||||
|
||||
.
|
||||
|
||||
### Try:
|
||||
1. If you get the error *"The JAVA_HOME environment variable points to a missing folder"* or *"Java runtime could not be located"*, please make sure that the environment variable JAVA_HOME points to a valid JDK. Otherwise, ignore this step.
|
||||
2. Run VS Code command *"Java: Update project configuration"* to force the language server to reload the current project.
|
||||
3. Try cleaning the stale workspace cache. Quit all VS Code processes and clean the following cache directory:
|
||||
- Windows : %APPDATA%\Code\User\workspaceStorage\
|
||||
- MacOS : $HOME/Library/Application Support/Code/User/workspaceStorage/
|
||||
- Linux : $HOME/.config/Code/User/workspaceStorage/
|
||||
4. Try more [troubleshooting guide](https://github.com/redhat-developer/vscode-java/wiki/Troubleshooting) from the language server product site.
|
||||
|
||||
## Failed to resolve classpath:
|
||||
### Reason:
|
||||
In launch mode, the debugger resolves the classpaths automatically based on the given `mainClass` and `projectName`. It looks for the class specified by `mainClass` as the entry point for launching an application. If there are multiple classes with the same name in the current workspace, the debugger uses the one inside the project specified by `projectName`.
|
||||
|
||||
### Try:
|
||||
1. Check whether the class name specified in `mainClass` exists and is in the right form. The debugger only works with fully qualified class names, e.g. `org.microsoft.app.Main`.
|
||||
2. Check whether the `projectName` is correct. The actual project name is not always the same to the folder name you see in the File Explorer. Please check the value specified by `projectDescription/name` in the *.project* file, or the `artificatId` in the *pom.xml* for maven project, or the folder name for gradle project.
|
||||
3. If the problem persists, please try to use the debugger to regenerate the debug configurations in *launch.json*. Remove the existing *launch.json* file and press F5. The debugger will automatically generate a new *launch.json* with the right debug configurations.
|
||||
|
||||
## Request type "xyz" is not supported. Only "launch" and "attach" are supported.
|
||||
### Reason:
|
||||
The value specified in `request` option of *launch.json* is incorrect.
|
||||
|
||||
### Try:
|
||||
1. Reference the VS Code official document [launch configurations](https://code.visualstudio.com/docs/editor/debugging#_launch-configurations) about how to configure *launch.json*.
|
||||
2. Try to use the debugger to regenerate the debug configurations in *launch.json*. Remove the existing *launch.json* file and press F5. The debugger will automatically generate a new *launch.json* with the right debug configurations.
|
||||
|
||||
## Failed to complete hot code replace:
|
||||
### Reason:
|
||||
This error indicates you are doing `Hot Code Replace`. The `Hot Code Replace` feature depends on the underlying JVM implementation. If you get this error, that indicates the new changes cannot be hot replaced by JVM.
|
||||
|
||||
### Try:
|
||||
1. Restart your application to apply the new changes. Or ignore the message, and continue to debug.
|
||||
2. You can disable the hot code replace feature by changing the user setting `"java.debug.settings.enableHotCodeReplace": false`.
|
||||
|
||||
## Please specify the host name and the port of the remote debuggee in the launch.json.
|
||||
### Reason:
|
||||
This error indicates you are debugging a remote Java application. The reason is that you don't configure the remote machine's host name and debug port correctly.
|
||||
|
||||
### Try:
|
||||
1. Check whether the remote Java application is launched in debug mode. The typical command to enable debug mode is like *"java -agentlib:jdwp=transport=dt_socket,address=5005,server=y,suspend=n -classpath \<classpath list\> MyMainClass"*, where the parameter *"address=5005"* represents the target JVM exposes *5005* as the debug port.
|
||||
2. Check the debug port is not blocked by the remote machine's firewall.
|
||||
|
||||
## Failed to evaluate. Reason: Cannot evaluate because the thread is resumed.
|
||||
### Reason:
|
||||
There are two possible reasons for this error.
|
||||
- Reason 1: you try to evaluate an expression when the target thread is running. Evaluation only works when your program is on suspend, for example, stopping at a breakpoint or stepping in/out/over.
|
||||
- Reason 2: you take the VS Code DEBUG CONSOLE view for program input by mistake. DEBUG CONSOLE only accepts input for evaluation, not for program console input.
|
||||
|
||||
### Try:
|
||||
1. For Reason 1, try to add a breakpoint and stop your program there, then evaluate the expression.
|
||||
2. For Reason 2, try to change the `console` option in the *launch.json* to `externalTerminal` or `integratedTerminal`. This is the official solution for program console input.
|
||||
|
||||
## The DEBUG CONSOLE throws Error: Could not find or load main class xyz
|
||||
### Reason:
|
||||
You configure the incorrect main class name in `mainClass` of *launch.json*.
|
||||
|
||||
### Try:
|
||||
1. Check whether the class name specified in `mainClass` exists and is in the right form.
|
||||
2. If the problem persists, it's probably because the language server doesn't load your project correctly. Please reference *"Java Language Support extension fails to start"* paragraph for more troubleshooting info.
|
||||
|
||||
## The DEBUG CONSOLE throws ClassNotFoundException
|
||||
### Reason:
|
||||
This error indicates your application attempts to reference some classes which are not found in the entire classpaths.
|
||||
|
||||
### Try:
|
||||
1. Check whether you configure the required libraries in the dependency settings file (e.g. *pom.xml*).
|
||||
2. Run VS Code command *"Java: Force Java compilation"* to force the language server to rebuild the current project.
|
||||
3. If the problem persists, it's probably because the language server doesn't load your project correctly. Please reference *"Java Language Support extension fails to start"* paragraph for more troubleshooting info.
|
||||
|
||||
## Cannot find a class with the main method
|
||||
### Reason:
|
||||
When the `mainClass` is unconfigured in the *launch.json*, the debugger will resolve a class with main method automatically. This error indicates the debugger doesn't find any main class in the whole workspace.
|
||||
|
||||
### Try:
|
||||
1. Check at least one main class exists in your workspace.
|
||||
2. If no main class exists, please create a main class first. Otherwise, it's probably because the language server fails to start. Please reference *"Java Language Support extension fails to start"* paragraph for more troubleshooting info.
|
|
@ -1742,6 +1742,11 @@
|
|||
"integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=",
|
||||
"dev": true
|
||||
},
|
||||
"is-wsl": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
|
||||
"integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0="
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
|
@ -2301,6 +2306,14 @@
|
|||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"opn": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz",
|
||||
"integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==",
|
||||
"requires": {
|
||||
"is-wsl": "1.1.0"
|
||||
}
|
||||
},
|
||||
"orchestrator": {
|
||||
"version": "0.3.8",
|
||||
"resolved": "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.8.tgz",
|
||||
|
|
|
@ -384,6 +384,7 @@
|
|||
"vscode": "^1.1.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"opn": "^5.3.0",
|
||||
"vscode-extension-telemetry": "0.0.18"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
// Licensed under the MIT license.
|
||||
|
||||
import * as vscode from "vscode";
|
||||
import TelemetryReporter from "vscode-extension-telemetry";
|
||||
import * as commands from "./commands";
|
||||
import { logger, Type } from "./logger";
|
||||
import * as utility from "./utility";
|
||||
|
||||
export class JavaDebugConfigurationProvider implements vscode.DebugConfigurationProvider {
|
||||
private isUserSettingsDirty: boolean = true;
|
||||
constructor(private _reporter: TelemetryReporter) {
|
||||
constructor() {
|
||||
vscode.workspace.onDidChangeConfiguration((event) => {
|
||||
if (vscode.debug.activeDebugSession) {
|
||||
this.isUserSettingsDirty = false;
|
||||
|
@ -132,25 +133,28 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration
|
|||
config.classPaths = result[1];
|
||||
}
|
||||
if (this.isEmptyArray(config.classPaths) && this.isEmptyArray(config.modulePaths)) {
|
||||
const hintMessage = "Cannot resolve the modulepaths/classpaths automatically, please specify the value in the launch.json.";
|
||||
vscode.window.showErrorMessage(hintMessage);
|
||||
this.log("usageError", hintMessage);
|
||||
utility.showErrorMessageWithTroubleshooting({
|
||||
message: "Cannot resolve the modulepaths/classpaths automatically, please specify the value in the launch.json.",
|
||||
type: Type.USAGEERROR,
|
||||
});
|
||||
return undefined;
|
||||
}
|
||||
} else if (config.request === "attach") {
|
||||
if (!config.hostName || !config.port) {
|
||||
vscode.window.showErrorMessage("Please specify the host name and the port of the remote debuggee in the launch.json.");
|
||||
this.log("usageError", "Please specify the host name and the port of the remote debuggee in the launch.json.");
|
||||
utility.showErrorMessageWithTroubleshooting({
|
||||
message: "Please specify the host name and the port of the remote debuggee in the launch.json.",
|
||||
type: Type.USAGEERROR,
|
||||
});
|
||||
return undefined;
|
||||
}
|
||||
} else {
|
||||
const ans = await vscode.window.showErrorMessage(
|
||||
// tslint:disable-next-line:max-line-length
|
||||
"Request type \"" + config.request + "\" is not supported. Only \"launch\" and \"attach\" are supported.", "Open launch.json");
|
||||
const ans = await utility.showErrorMessageWithTroubleshooting({
|
||||
message: `Request type "${config.request}" is not supported. Only "launch" and "attach" are supported.`,
|
||||
type: Type.USAGEERROR,
|
||||
}, "Open launch.json");
|
||||
if (ans === "Open launch.json") {
|
||||
await vscode.commands.executeCommand(commands.VSCODE_ADD_DEBUGCONFIGURATION);
|
||||
}
|
||||
this.log("usageError", "Illegal request type in launch.json");
|
||||
return undefined;
|
||||
}
|
||||
const debugServerPort = await startDebugSession();
|
||||
|
@ -158,40 +162,35 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration
|
|||
config.debugServer = debugServerPort;
|
||||
return config;
|
||||
} else {
|
||||
this.log("exception", "Failed to start debug server.");
|
||||
logger.logMessage(Type.EXCEPTION, "Failed to start debug server.");
|
||||
// Information for diagnostic:
|
||||
console.log("Cannot find a port for debugging session");
|
||||
return undefined;
|
||||
}
|
||||
} catch (ex) {
|
||||
const errorMessage = (ex && ex.message) || ex;
|
||||
vscode.window.showErrorMessage(String(errorMessage));
|
||||
if (this._reporter) {
|
||||
const exception = (ex && ex.data && ex.data.cause)
|
||||
|| { stackTrace: [], detailMessage: String((ex && ex.message) || ex || "Unknown exception") };
|
||||
const properties = {
|
||||
message: "",
|
||||
stackTrace: "",
|
||||
};
|
||||
if (exception && typeof exception === "object") {
|
||||
properties.message = exception.detailMessage;
|
||||
properties.stackTrace = (Array.isArray(exception.stackTrace) && JSON.stringify(exception.stackTrace))
|
||||
|| String(exception.stackTrace);
|
||||
} else {
|
||||
properties.message = String(exception);
|
||||
}
|
||||
this._reporter.sendTelemetryEvent("exception", properties);
|
||||
const exception = (ex && ex.data && ex.data.cause)
|
||||
|| { stackTrace: [], detailMessage: String((ex && ex.message) || ex || "Unknown exception") };
|
||||
const properties = {
|
||||
message: "",
|
||||
stackTrace: "",
|
||||
};
|
||||
if (exception && typeof exception === "object") {
|
||||
properties.message = exception.detailMessage;
|
||||
properties.stackTrace = (Array.isArray(exception.stackTrace) && JSON.stringify(exception.stackTrace))
|
||||
|| String(exception.stackTrace);
|
||||
} else {
|
||||
properties.message = String(exception);
|
||||
}
|
||||
utility.showErrorMessageWithTroubleshooting({
|
||||
message: String(errorMessage),
|
||||
type: Type.EXCEPTION,
|
||||
details: properties,
|
||||
});
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
private log(type: string, message: string) {
|
||||
if (this._reporter) {
|
||||
this._reporter.sendTelemetryEvent(type, { message });
|
||||
}
|
||||
}
|
||||
|
||||
private isEmptyArray(configItems: any): boolean {
|
||||
return !Array.isArray(configItems) || !configItems.length;
|
||||
}
|
||||
|
@ -199,8 +198,10 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration
|
|||
private async chooseMainClass(folder: vscode.WorkspaceFolder | undefined): Promise<IMainClassOption | undefined> {
|
||||
const res = await resolveMainClass(folder ? folder.uri : undefined);
|
||||
if (res.length === 0) {
|
||||
vscode.window.showErrorMessage(
|
||||
"Cannot find a class with the main method.");
|
||||
utility.showErrorMessageWithTroubleshooting({
|
||||
message: "Cannot find a class with the main method.",
|
||||
type: Type.USAGEERROR,
|
||||
});
|
||||
return undefined;
|
||||
}
|
||||
const pickItems = res.map((item) => {
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
export const JAVA_LANGID: string = "java";
|
||||
export const HCR_EVENT = "hotcodereplace";
|
||||
export const USER_NOTIFICATION_EVENT = "usernotification";
|
||||
|
|
|
@ -3,49 +3,41 @@
|
|||
|
||||
import * as path from "path";
|
||||
import * as vscode from "vscode";
|
||||
import TelemetryReporter from "vscode-extension-telemetry";
|
||||
import * as commands from "./commands";
|
||||
import { JavaDebugConfigurationProvider } from "./configurationProvider";
|
||||
import { HCR_EVENT, JAVA_LANGID, USER_NOTIFICATION_EVENT } from "./constants";
|
||||
import { handleHotCodeReplaceCustomEvent, initializeHotCodeReplace } from "./hotCodeReplace";
|
||||
import { logger, Type } from "./logger";
|
||||
import * as utility from "./utility";
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
// The reporter will be initialized by the later telemetry handler.
|
||||
let reporter: TelemetryReporter = null;
|
||||
logger.initialize(context);
|
||||
logger.log(Type.ACTIVATEEXTENSION, {}); // TODO: Activation belongs to usage data, remove this line.
|
||||
logger.log(Type.USAGEDATA, {
|
||||
description: "activateExtension",
|
||||
});
|
||||
|
||||
// Telemetry.
|
||||
const extensionPackage = require(context.asAbsolutePath("./package.json"));
|
||||
if (extensionPackage) {
|
||||
const packageInfo = {
|
||||
name: extensionPackage.name,
|
||||
version: extensionPackage.version,
|
||||
aiKey: extensionPackage.aiKey,
|
||||
};
|
||||
if (packageInfo.aiKey) {
|
||||
reporter = new TelemetryReporter(packageInfo.name, packageInfo.version, packageInfo.aiKey);
|
||||
reporter.sendTelemetryEvent("activateExtension", {});
|
||||
const measureKeys = ["duration"];
|
||||
vscode.debug.onDidTerminateDebugSession(() => {
|
||||
fetchUsageData().then((ret) => {
|
||||
if (Array.isArray(ret) && ret.length) {
|
||||
ret.forEach((entry) => {
|
||||
const commonProperties: any = {};
|
||||
const measureProperties: any = {};
|
||||
for (const key of Object.keys(entry)) {
|
||||
if (measureKeys.indexOf(key) >= 0) {
|
||||
measureProperties[key] = entry[key];
|
||||
} else {
|
||||
commonProperties[key] = String(entry[key]);
|
||||
}
|
||||
}
|
||||
reporter.sendTelemetryEvent(entry.scope === "exception" ? "exception" : "usageData", commonProperties, measureProperties);
|
||||
});
|
||||
const measureKeys = ["duration"];
|
||||
vscode.debug.onDidTerminateDebugSession(() => {
|
||||
fetchUsageData().then((ret) => {
|
||||
if (Array.isArray(ret) && ret.length) {
|
||||
ret.forEach((entry) => {
|
||||
const commonProperties: any = {};
|
||||
const measureProperties: any = {};
|
||||
for (const key of Object.keys(entry)) {
|
||||
if (measureKeys.indexOf(key) >= 0) {
|
||||
measureProperties[key] = entry[key];
|
||||
} else {
|
||||
commonProperties[key] = String(entry[key]);
|
||||
}
|
||||
}
|
||||
logger.log(entry.scope === "exception" ? Type.EXCEPTION : Type.USAGEDATA, commonProperties, measureProperties);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider("java", new JavaDebugConfigurationProvider(reporter)));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider("java", new JavaDebugConfigurationProvider()));
|
||||
context.subscriptions.push(vscode.commands.registerCommand("JavaDebug.SpecifyProgramArgs", async () => {
|
||||
return specifyProgramArguments(context);
|
||||
}));
|
||||
|
@ -69,9 +61,13 @@ export function deactivate() {
|
|||
|
||||
function handleUserNotification(customEvent) {
|
||||
if (customEvent.body.notificationType === "ERROR") {
|
||||
vscode.window.showErrorMessage(customEvent.body.message);
|
||||
utility.showErrorMessageWithTroubleshooting({
|
||||
message: customEvent.body.message,
|
||||
});
|
||||
} else if (customEvent.body.notificationType === "WARNING") {
|
||||
vscode.window.showWarningMessage(customEvent.body.message);
|
||||
utility.showWarningMessageWithTroubleshooting({
|
||||
message: customEvent.body.message,
|
||||
});
|
||||
} else {
|
||||
vscode.window.showInformationMessage(customEvent.body.message);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
import * as vscode from "vscode";
|
||||
|
||||
import { HCR_EVENT, JAVA_LANGID } from "./constants";
|
||||
import * as utility from "./utility";
|
||||
|
||||
const suppressedReasons: Set<string> = new Set();
|
||||
|
||||
|
@ -40,9 +41,9 @@ export function handleHotCodeReplaceCustomEvent(hcrEvent) {
|
|||
|
||||
if (hcrEvent.body.changeType === HcrChangeType.ERROR || hcrEvent.body.changeType === HcrChangeType.WARNING) {
|
||||
if (!suppressedReasons.has(hcrEvent.body.message)) {
|
||||
vscode.window.showInformationMessage(
|
||||
`Hot code replace failed - ${hcrEvent.body.message}. Would you like to restart the debug session?`,
|
||||
YES_BUTTON, NO_BUTTON, NEVER_BUTTON).then((res) => {
|
||||
utility.showWarningMessageWithTroubleshooting({
|
||||
message: `Hot code replace failed - ${hcrEvent.body.message}. Would you like to restart the debug session?`,
|
||||
}, YES_BUTTON, NO_BUTTON, NEVER_BUTTON).then((res) => {
|
||||
if (res === NEVER_BUTTON) {
|
||||
suppressedReasons.add(hcrEvent.body.message);
|
||||
} else if (res === YES_BUTTON) {
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import * as vscode from "vscode";
|
||||
import TelemetryReporter from "vscode-extension-telemetry";
|
||||
|
||||
export enum Type {
|
||||
EXCEPTION = "exception",
|
||||
USAGEDATA = "usageData",
|
||||
USAGEERROR = "usageError",
|
||||
ACTIVATEEXTENSION = "activateExtension", // TODO: Activation belongs to usage data, remove this category.
|
||||
}
|
||||
|
||||
class Logger {
|
||||
private reporter: TelemetryReporter = null;
|
||||
|
||||
public initialize(context: vscode.ExtensionContext): void {
|
||||
if (this.reporter) {
|
||||
return;
|
||||
}
|
||||
|
||||
const extensionPackage = require(context.asAbsolutePath("./package.json"));
|
||||
if (extensionPackage) {
|
||||
const packageInfo = {
|
||||
name: extensionPackage.name,
|
||||
version: extensionPackage.version,
|
||||
aiKey: extensionPackage.aiKey,
|
||||
};
|
||||
if (packageInfo.aiKey) {
|
||||
this.reporter = new TelemetryReporter(packageInfo.name, packageInfo.version, packageInfo.aiKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public log(type: Type, properties?: { [key: string]: string; }, measures?: { [key: string]: number; }): void {
|
||||
if (!this.reporter) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.reporter.sendTelemetryEvent(type, properties, measures);
|
||||
}
|
||||
|
||||
public logMessage(type: Type, message: string): void {
|
||||
this.log(type, { message });
|
||||
}
|
||||
}
|
||||
|
||||
export const logger = new Logger();
|
|
@ -0,0 +1,74 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import * as opn from "opn";
|
||||
import * as vscode from "vscode";
|
||||
import { logger, Type } from "./logger";
|
||||
|
||||
const TROUBLESHOOTING_LINK = "https://github.com/Microsoft/vscode-java-debug/blob/master/Troubleshooting.md";
|
||||
const LEARN_MORE = "Learn More";
|
||||
|
||||
interface IMessage {
|
||||
message: string;
|
||||
type?: Type;
|
||||
details?: { [key: string]: string; };
|
||||
}
|
||||
|
||||
function logMessage(message: IMessage): void {
|
||||
if (!message.type) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.details) {
|
||||
logger.log(message.type, message.details);
|
||||
} else {
|
||||
logger.logMessage(message.type, message.message);
|
||||
}
|
||||
}
|
||||
|
||||
export async function showInformationMessage(message: IMessage, ...items: string[]): Promise<string | undefined> {
|
||||
logMessage(message);
|
||||
return await vscode.window.showInformationMessage(message.message, ...items);
|
||||
}
|
||||
|
||||
export async function showWarningMessage(message: IMessage, ...items: string[]): Promise<string | undefined> {
|
||||
logMessage(message);
|
||||
return await vscode.window.showWarningMessage(message.message, ...items);
|
||||
}
|
||||
|
||||
export async function showErrorMessage(message: IMessage, ...items: string[]): Promise<string | undefined> {
|
||||
logMessage(message);
|
||||
return await vscode.window.showErrorMessage(message.message, ...items);
|
||||
}
|
||||
|
||||
export async function showInformationMessageWithTroubleshooting(message: IMessage, ...items: string[]): Promise<string | undefined> {
|
||||
const choice = await showInformationMessage(message, ...items, LEARN_MORE);
|
||||
return handleTroubleshooting(choice, message.message);
|
||||
}
|
||||
|
||||
export async function showWarningMessageWithTroubleshooting(message: IMessage, ...items: string[]): Promise<string | undefined> {
|
||||
const choice = await showWarningMessage(message, ...items, LEARN_MORE);
|
||||
return handleTroubleshooting(choice, message.message);
|
||||
}
|
||||
|
||||
export async function showErrorMessageWithTroubleshooting(message: IMessage, ...items: string[]): Promise<string | undefined> {
|
||||
const choice = await showErrorMessage(message, ...items, LEARN_MORE);
|
||||
return handleTroubleshooting(choice, message.message);
|
||||
}
|
||||
|
||||
function openLink(url: string): void {
|
||||
opn(url);
|
||||
}
|
||||
|
||||
function handleTroubleshooting(choice: string, message: string): string | undefined {
|
||||
if (choice === LEARN_MORE) {
|
||||
openLink(TROUBLESHOOTING_LINK);
|
||||
logger.log(Type.USAGEDATA, {
|
||||
troubleshooting: "yes",
|
||||
troubleshootingMessage: message,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
return choice;
|
||||
}
|
Loading…
Reference in New Issue