Reduce duplication in the logs when errors occur in CLI commands
This commit is contained in:
parent
a2dc5ffaff
commit
8295705640
9 changed files with 71 additions and 28 deletions
6
lib/analyze.js
generated
6
lib/analyze.js
generated
|
|
@ -237,12 +237,8 @@ async function runQueries(sarifFolder, memoryFlag, addSnippetsFlag, threadsFlag,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
logger.info(String(e));
|
|
||||||
if (e instanceof Error) {
|
|
||||||
logger.info(e.stack);
|
|
||||||
}
|
|
||||||
statusReport.analyze_failure_language = language;
|
statusReport.analyze_failure_language = language;
|
||||||
throw new CodeQLAnalysisError(statusReport, `Error running analysis for ${language}: ${e}`);
|
throw new CodeQLAnalysisError(statusReport, `Error running analysis for ${language}: ${util.wrapError(e).message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return statusReport;
|
return statusReport;
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
21
lib/codeql.js
generated
21
lib/codeql.js
generated
|
|
@ -37,15 +37,25 @@ const setupCodeql = __importStar(require("./setup-codeql"));
|
||||||
const util = __importStar(require("./util"));
|
const util = __importStar(require("./util"));
|
||||||
const util_1 = require("./util");
|
const util_1 = require("./util");
|
||||||
class CommandInvocationError extends Error {
|
class CommandInvocationError extends Error {
|
||||||
constructor(cmd, args, exitCode, error, output) {
|
constructor(cmd, args, exitCode, stderr, stdout) {
|
||||||
const prettyCommand = [cmd, ...args]
|
const prettyCommand = [cmd, ...args]
|
||||||
.map((x) => (x.includes(" ") ? `'${x}'` : x))
|
.map((x) => (x.includes(" ") ? `'${x}'` : x))
|
||||||
.join(" ");
|
.join(" ");
|
||||||
|
const fatalErrors = extractFatalErrors(stderr);
|
||||||
|
const lastLine = stderr.trim().split("\n").pop()?.trim();
|
||||||
|
let error = fatalErrors
|
||||||
|
? ` and error was: ${fatalErrors.trim()}`
|
||||||
|
: lastLine
|
||||||
|
? ` and last log line was: ${lastLine}`
|
||||||
|
: "";
|
||||||
|
if (error[error.length - 1] !== ".") {
|
||||||
|
error += ".";
|
||||||
|
}
|
||||||
super(`Encountered a fatal error while running "${prettyCommand}". ` +
|
super(`Encountered a fatal error while running "${prettyCommand}". ` +
|
||||||
`Exit code was ${exitCode} and error was: ${error.trim()}`);
|
`Exit code was ${exitCode}${error} See the logs for more details.`);
|
||||||
this.exitCode = exitCode;
|
this.exitCode = exitCode;
|
||||||
this.error = error;
|
this.stderr = stderr;
|
||||||
this.output = output;
|
this.stdout = stdout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.CommandInvocationError = CommandInvocationError;
|
exports.CommandInvocationError = CommandInvocationError;
|
||||||
|
|
@ -775,7 +785,6 @@ async function runTool(cmd, args = [], opts = {}) {
|
||||||
...(opts.stdin ? { input: Buffer.from(opts.stdin || "") } : {}),
|
...(opts.stdin ? { input: Buffer.from(opts.stdin || "") } : {}),
|
||||||
}).exec();
|
}).exec();
|
||||||
if (exitCode !== 0) {
|
if (exitCode !== 0) {
|
||||||
error = extractFatalErrors(error) || error;
|
|
||||||
throw new CommandInvocationError(cmd, args, exitCode, error, output);
|
throw new CommandInvocationError(cmd, args, exitCode, error, output);
|
||||||
}
|
}
|
||||||
return output;
|
return output;
|
||||||
|
|
@ -956,7 +965,7 @@ function isNoCodeFoundError(e) {
|
||||||
* This can be removed once support for CodeQL 2.11.6 is removed.
|
* This can be removed once support for CodeQL 2.11.6 is removed.
|
||||||
*/
|
*/
|
||||||
const javascriptNoCodeFoundWarning = "No JavaScript or TypeScript code found.";
|
const javascriptNoCodeFoundWarning = "No JavaScript or TypeScript code found.";
|
||||||
return e.exitCode === 32 || e.error.includes(javascriptNoCodeFoundWarning);
|
return e.exitCode === 32 || e.stderr.includes(javascriptNoCodeFoundWarning);
|
||||||
}
|
}
|
||||||
async function isDiagnosticsExportInvalidSarifFixed(codeql) {
|
async function isDiagnosticsExportInvalidSarifFixed(codeql) {
|
||||||
return await util.codeQlVersionAbove(codeql, exports.CODEQL_VERSION_DIAGNOSTICS_EXPORT_FIXED);
|
return await util.codeQlVersionAbove(codeql, exports.CODEQL_VERSION_DIAGNOSTICS_EXPORT_FIXED);
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
16
lib/codeql.test.js
generated
16
lib/codeql.test.js
generated
|
|
@ -695,7 +695,7 @@ for (const { featureEnabled, codeqlVersion, flagPassed, negativeFlagPassed, } of
|
||||||
sinon.stub(safeWhich, "safeWhich").resolves("");
|
sinon.stub(safeWhich, "safeWhich").resolves("");
|
||||||
await t.throwsAsync(async () => await codeqlObject.finalizeDatabase("db", "--threads=2", "--ram=2048"), {
|
await t.throwsAsync(async () => await codeqlObject.finalizeDatabase("db", "--threads=2", "--ram=2048"), {
|
||||||
message: 'Encountered a fatal error while running "codeql-for-testing database finalize --finalize-dataset --threads=2 --ram=2048 db". ' +
|
message: 'Encountered a fatal error while running "codeql-for-testing database finalize --finalize-dataset --threads=2 --ram=2048 db". ' +
|
||||||
`Exit code was 32 and error was: ${cliMessage}`,
|
`Exit code was 32 and last log line was: ${cliMessage} See the logs for more details.`,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
(0, ava_1.default)("runTool summarizes several fatal errors", async (t) => {
|
(0, ava_1.default)("runTool summarizes several fatal errors", async (t) => {
|
||||||
|
|
@ -710,7 +710,19 @@ for (const { featureEnabled, codeqlVersion, flagPassed, negativeFlagPassed, } of
|
||||||
sinon.stub(safeWhich, "safeWhich").resolves("");
|
sinon.stub(safeWhich, "safeWhich").resolves("");
|
||||||
await t.throwsAsync(async () => await codeqlObject.finalizeDatabase("db", "--threads=2", "--ram=2048"), {
|
await t.throwsAsync(async () => await codeqlObject.finalizeDatabase("db", "--threads=2", "--ram=2048"), {
|
||||||
message: 'Encountered a fatal error while running "codeql-for-testing database finalize --finalize-dataset --threads=2 --ram=2048 db". ' +
|
message: 'Encountered a fatal error while running "codeql-for-testing database finalize --finalize-dataset --threads=2 --ram=2048 db". ' +
|
||||||
`Exit code was 32 and error was: ${datasetImportError}. Context: ${heapError}.`,
|
`Exit code was 32 and error was: ${datasetImportError}. Context: ${heapError}. See the logs for more details.`,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
(0, ava_1.default)("runTool outputs last line of stderr if fatal error could not be found", async (t) => {
|
||||||
|
const cliStderr = "line1\nline2\nline3\nline4\nline5";
|
||||||
|
stubToolRunnerConstructor(32, cliStderr);
|
||||||
|
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||||
|
sinon.stub(codeqlObject, "getVersion").resolves((0, testing_utils_1.makeVersionInfo)("2.12.4"));
|
||||||
|
// safeWhich throws because of the test CodeQL object.
|
||||||
|
sinon.stub(safeWhich, "safeWhich").resolves("");
|
||||||
|
await t.throwsAsync(async () => await codeqlObject.finalizeDatabase("db", "--threads=2", "--ram=2048"), {
|
||||||
|
message: 'Encountered a fatal error while running "codeql-for-testing database finalize --finalize-dataset --threads=2 --ram=2048 db". ' +
|
||||||
|
"Exit code was 32 and last log line was: line5. See the logs for more details.",
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
function stubToolRunnerConstructor(exitCode = 0, stderr) {
|
function stubToolRunnerConstructor(exitCode = 0, stderr) {
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -394,14 +394,10 @@ export async function runQueries(
|
||||||
await runPrintLinesOfCode(language);
|
await runPrintLinesOfCode(language);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.info(String(e));
|
|
||||||
if (e instanceof Error) {
|
|
||||||
logger.info(e.stack!);
|
|
||||||
}
|
|
||||||
statusReport.analyze_failure_language = language;
|
statusReport.analyze_failure_language = language;
|
||||||
throw new CodeQLAnalysisError(
|
throw new CodeQLAnalysisError(
|
||||||
statusReport,
|
statusReport,
|
||||||
`Error running analysis for ${language}: ${e}`,
|
`Error running analysis for ${language}: ${util.wrapError(e).message}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1133,7 +1133,7 @@ test("database finalize does not override no code found error on CodeQL 2.12.4",
|
||||||
{
|
{
|
||||||
message:
|
message:
|
||||||
'Encountered a fatal error while running "codeql-for-testing database finalize --finalize-dataset --threads=2 --ram=2048 db". ' +
|
'Encountered a fatal error while running "codeql-for-testing database finalize --finalize-dataset --threads=2 --ram=2048 db". ' +
|
||||||
`Exit code was 32 and error was: ${cliMessage}`,
|
`Exit code was 32 and last log line was: ${cliMessage} See the logs for more details.`,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
@ -1158,7 +1158,26 @@ test("runTool summarizes several fatal errors", async (t) => {
|
||||||
{
|
{
|
||||||
message:
|
message:
|
||||||
'Encountered a fatal error while running "codeql-for-testing database finalize --finalize-dataset --threads=2 --ram=2048 db". ' +
|
'Encountered a fatal error while running "codeql-for-testing database finalize --finalize-dataset --threads=2 --ram=2048 db". ' +
|
||||||
`Exit code was 32 and error was: ${datasetImportError}. Context: ${heapError}.`,
|
`Exit code was 32 and error was: ${datasetImportError}. Context: ${heapError}. See the logs for more details.`,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("runTool outputs last line of stderr if fatal error could not be found", async (t) => {
|
||||||
|
const cliStderr = "line1\nline2\nline3\nline4\nline5";
|
||||||
|
stubToolRunnerConstructor(32, cliStderr);
|
||||||
|
const codeqlObject = await codeql.getCodeQLForTesting();
|
||||||
|
sinon.stub(codeqlObject, "getVersion").resolves(makeVersionInfo("2.12.4"));
|
||||||
|
// safeWhich throws because of the test CodeQL object.
|
||||||
|
sinon.stub(safeWhich, "safeWhich").resolves("");
|
||||||
|
|
||||||
|
await t.throwsAsync(
|
||||||
|
async () =>
|
||||||
|
await codeqlObject.finalizeDatabase("db", "--threads=2", "--ram=2048"),
|
||||||
|
{
|
||||||
|
message:
|
||||||
|
'Encountered a fatal error while running "codeql-for-testing database finalize --finalize-dataset --threads=2 --ram=2048 db". ' +
|
||||||
|
"Exit code was 32 and last log line was: line5. See the logs for more details.",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -54,15 +54,27 @@ export class CommandInvocationError extends Error {
|
||||||
cmd: string,
|
cmd: string,
|
||||||
args: string[],
|
args: string[],
|
||||||
public exitCode: number,
|
public exitCode: number,
|
||||||
public error: string,
|
public stderr: string,
|
||||||
public output: string,
|
public stdout: string,
|
||||||
) {
|
) {
|
||||||
const prettyCommand = [cmd, ...args]
|
const prettyCommand = [cmd, ...args]
|
||||||
.map((x) => (x.includes(" ") ? `'${x}'` : x))
|
.map((x) => (x.includes(" ") ? `'${x}'` : x))
|
||||||
.join(" ");
|
.join(" ");
|
||||||
|
|
||||||
|
const fatalErrors = extractFatalErrors(stderr);
|
||||||
|
const lastLine = stderr.trim().split("\n").pop()?.trim();
|
||||||
|
let error = fatalErrors
|
||||||
|
? ` and error was: ${fatalErrors.trim()}`
|
||||||
|
: lastLine
|
||||||
|
? ` and last log line was: ${lastLine}`
|
||||||
|
: "";
|
||||||
|
if (error[error.length - 1] !== ".") {
|
||||||
|
error += ".";
|
||||||
|
}
|
||||||
|
|
||||||
super(
|
super(
|
||||||
`Encountered a fatal error while running "${prettyCommand}". ` +
|
`Encountered a fatal error while running "${prettyCommand}". ` +
|
||||||
`Exit code was ${exitCode} and error was: ${error.trim()}`,
|
`Exit code was ${exitCode}${error} See the logs for more details.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1238,7 +1250,6 @@ async function runTool(
|
||||||
...(opts.stdin ? { input: Buffer.from(opts.stdin || "") } : {}),
|
...(opts.stdin ? { input: Buffer.from(opts.stdin || "") } : {}),
|
||||||
}).exec();
|
}).exec();
|
||||||
if (exitCode !== 0) {
|
if (exitCode !== 0) {
|
||||||
error = extractFatalErrors(error) || error;
|
|
||||||
throw new CommandInvocationError(cmd, args, exitCode, error, output);
|
throw new CommandInvocationError(cmd, args, exitCode, error, output);
|
||||||
}
|
}
|
||||||
return output;
|
return output;
|
||||||
|
|
@ -1454,7 +1465,7 @@ function isNoCodeFoundError(e: CommandInvocationError): boolean {
|
||||||
*/
|
*/
|
||||||
const javascriptNoCodeFoundWarning =
|
const javascriptNoCodeFoundWarning =
|
||||||
"No JavaScript or TypeScript code found.";
|
"No JavaScript or TypeScript code found.";
|
||||||
return e.exitCode === 32 || e.error.includes(javascriptNoCodeFoundWarning);
|
return e.exitCode === 32 || e.stderr.includes(javascriptNoCodeFoundWarning);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function isDiagnosticsExportInvalidSarifFixed(
|
async function isDiagnosticsExportInvalidSarifFixed(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue