Skip to content

Commit 8a93245

Browse files
committed
Improve Java detection error reporting
This improves console output for failing spawn calls (e.g. due to ENOENT errors and similar), avoids reporting ENOENT specifically as unusual (lots of people have bad JAVA_HOME etc) and ensures we report issues only _once_ rather than reporting them every time the JVM detection is checked.
1 parent 5a75fd9 commit 8a93245

File tree

1 file changed

+24
-9
lines changed

1 file changed

+24
-9
lines changed

src/interceptors/jvm.ts

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { OVERRIDE_JAVA_AGENT } from './terminal/terminal-env-overrides';
99
import { reportError } from '../error-tracking';
1010
import { delay } from '../util/promise';
1111
import { commandExists, canAccess } from '../util/fs';
12+
import { ErrorLike } from '../util/error';
1213

1314
type JvmTarget = { pid: string, name: string, interceptedByProxy: number | undefined };
1415

@@ -38,7 +39,12 @@ const javaBinPromise: Promise<string | false> = (async () => {
3839
const javaTestResults = await Promise.all(javaBinPaths.map(async (possibleJavaBin) => ({
3940
javaBin: possibleJavaBin,
4041
output: await testJavaBin(possibleJavaBin)
41-
.catch((e) => ({ exitCode: -1, stdout: '', stderr: e.toString() }))
42+
.catch((e) => ({
43+
exitCode: -1,
44+
spawnError: e as ErrorLike,
45+
stdout: '',
46+
stderr: ''
47+
}))
4248
})))
4349

4450
// Use the first Java in the list that succeeds:
@@ -50,26 +56,35 @@ const javaBinPromise: Promise<string | false> = (async () => {
5056
// Some Java binaries are present, but none are usable. Log the error output for debugging:
5157
javaTestResults.forEach((testResult) => {
5258
console.log(`Running ${testResult.javaBin}:`);
53-
console.log(testResult.output.stdout);
54-
console.log(testResult.output.stderr);
59+
60+
const { stdout, stderr } = testResult.output;
61+
if (stdout) console.log(stdout);
62+
if (stderr) console.log(stderr);
63+
if (!stdout && !stderr) console.log('[No output]');
64+
65+
if ('spawnError' in testResult.output) {
66+
const { spawnError } = testResult.output;
67+
console.log(spawnError.message || spawnError);
68+
}
5569
});
5670

5771
// The most common reason for this is that outdated Java versions (most notably Java 8) don't include
5872
// the necessary APIs to attach to remote JVMs. That's inconvenient, but unavoidable & not unusual.
5973
// Fortunately, I think most active Java developers do have a recent version of Java installed.
60-
const nonOutdatedJavaErrors = javaTestResults.filter(({ output }) =>
74+
const unusualJavaErrors = javaTestResults.filter(({ output }) =>
6175
!output.stderr.includes(OLD_JAVA_MISSING_ATTACH_CLASS) &&
62-
!output.stdout.includes(OLD_JAVA_MISSING_ATTACH_CLASS)
76+
!output.stdout.includes(OLD_JAVA_MISSING_ATTACH_CLASS) &&
77+
!('spawnError' in output && output.spawnError.code === 'ENOENT')
6378
);
6479

65-
if (nonOutdatedJavaErrors.length === 0) {
66-
console.warn('Only older Java versions were detected - Java attach APIs are not available');
67-
return false;
80+
if (unusualJavaErrors.length === 0) {
81+
console.warn('=> Java attach APIs are not available');
6882
} else {
6983
// If we find any other unexpected Java errors, we report them, to aid with debugging and
7084
// detecting issues with unusual JVMs.
71-
throw new Error(`JVM attach test failed unusually - exited with ${nonOutdatedJavaErrors[0].output.exitCode}`);
85+
reportError(new Error(`JVM attach test failed unusually - exited with ${unusualJavaErrors[0].output.exitCode}`));
7286
}
87+
return false;
7388
} else if (bestJava) {
7489
return bestJava.javaBin;
7590
} else {

0 commit comments

Comments
 (0)