Skip to content

Commit 88b28eb

Browse files
committed
Surface autobuild errors from stderr stream
1 parent f055b5e commit 88b28eb

File tree

6 files changed

+125
-24
lines changed

6 files changed

+125
-24
lines changed

lib/cli-errors.js

+28-10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/cli-errors.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/codeql.test.js

+29
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/codeql.test.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cli-errors.ts

+31-12
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,31 @@ export class CommandInvocationError extends Error {
2020
.join(" ");
2121

2222
const fatalErrors = extractFatalErrors(stderr);
23-
const lastLine = stderr.trim().split("\n").pop()?.trim();
24-
let error = fatalErrors
25-
? ` and error was: ${fatalErrors.trim()}`
26-
: lastLine
27-
? ` and last log line was: ${lastLine}`
28-
: "";
29-
if (error[error.length - 1] !== ".") {
30-
error += ".";
23+
const autobuildErrors = extractAutobuildErrors(stderr);
24+
let message: string;
25+
26+
if (fatalErrors) {
27+
message =
28+
`Encountered a fatal error while running "${prettyCommand}". ` +
29+
`Exit code was ${exitCode} and error was: ${fatalErrors.trim()} See the logs for more details.`;
30+
} else if (autobuildErrors) {
31+
const autobuildHelpLink =
32+
"https://docs.github.com/en/code-security/code-scanning/troubleshooting-code-scanning/automatic-build-failed";
33+
message =
34+
"We were unable to automatically build your code. Please provide manual build steps. " +
35+
`For more information, see ${autobuildHelpLink}. ` +
36+
`Encountered the following error: ${autobuildErrors}`;
37+
} else {
38+
let lastLine = stderr.trim().split("\n").pop()?.trim() || "";
39+
if (lastLine[lastLine.length - 1] !== ".") {
40+
lastLine += ".";
41+
}
42+
message =
43+
`Encountered a fatal error while running "${prettyCommand}". ` +
44+
`Exit code was ${exitCode} and last log line was: ${lastLine} See the logs for more details.`;
3145
}
3246

33-
super(
34-
`Encountered a fatal error while running "${prettyCommand}". ` +
35-
`Exit code was ${exitCode}${error} See the logs for more details.`,
36-
);
47+
super(message);
3748
}
3849
}
3950

@@ -96,6 +107,14 @@ function extractFatalErrors(error: string): string | undefined {
96107
return undefined;
97108
}
98109

110+
function extractAutobuildErrors(error: string): string | undefined {
111+
const pattern = /.*\[autobuild\] \[ERROR\] (.*)/gi;
112+
return (
113+
[...error.matchAll(pattern)].map((match) => match[1]).join("\n") ||
114+
undefined
115+
);
116+
}
117+
99118
function ensureEndsInPeriod(text: string): string {
100119
return text[text.length - 1] === "." ? text : `${text}.`;
101120
}

src/codeql.test.ts

+35
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import * as sinon from "sinon";
1212

1313
import * as actionsUtil from "./actions-util";
1414
import { GitHubApiDetails } from "./api-client";
15+
import { CommandInvocationError } from "./cli-errors";
1516
import * as codeql from "./codeql";
1617
import { AugmentationProperties, Config } from "./config-utils";
1718
import * as defaults from "./defaults.json";
@@ -967,6 +968,40 @@ test("runTool summarizes several fatal errors", async (t) => {
967968
);
968969
});
969970

971+
test("runTool summarizes autobuilder errors", async (t) => {
972+
const stderr = `
973+
[2019-09-18 12:00:00] [autobuild] A non-error message
974+
[2019-09-18 12:00:00] Untagged message
975+
[2019-09-18 12:00:00] [autobuild] [ERROR] Start of the error message
976+
[2019-09-18 12:00:00] [autobuild] An interspersed non-error message
977+
[2019-09-18 12:00:01] [autobuild] [ERROR] Some more context about the error message
978+
[2019-09-18 12:00:01] [autobuild] [ERROR] continued
979+
[2019-09-18 12:00:01] [autobuild] [ERROR] and finished here.
980+
[2019-09-18 12:00:01] [autobuild] A non-error message
981+
`;
982+
stubToolRunnerConstructor(1, stderr);
983+
const codeqlObject = await codeql.getCodeQLForTesting();
984+
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.12.4"));
985+
sinon.stub(codeqlObject, "resolveExtractor").resolves("/path/to/extractor");
986+
// safeWhich throws because of the test CodeQL object.
987+
sinon.stub(safeWhich, "safeWhich").resolves("");
988+
989+
await t.throwsAsync(
990+
async () => await codeqlObject.runAutobuild(Language.java, false),
991+
{
992+
instanceOf: CommandInvocationError,
993+
message:
994+
"We were unable to automatically build your code. Please provide manual build steps. " +
995+
"For more information, see " +
996+
"https://docs.github.com/en/code-security/code-scanning/troubleshooting-code-scanning/automatic-build-failed. " +
997+
"Encountered the following error: Start of the error message\n" +
998+
" Some more context about the error message\n" +
999+
" continued\n" +
1000+
" and finished here.",
1001+
},
1002+
);
1003+
});
1004+
9701005
test("runTool outputs last line of stderr if fatal error could not be found", async (t) => {
9711006
const cliStderr = "line1\nline2\nline3\nline4\nline5";
9721007
stubToolRunnerConstructor(32, cliStderr);

0 commit comments

Comments
 (0)