Add common CLI configuration error categories (#2130)

Co-authored-by: Henry Mercer <henry@henrymercer.name>
This commit is contained in:
Angela P Wen 2024-02-14 05:57:38 -08:00 committed by GitHub
parent bc64d12bb9
commit 7b30fefa68
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 238 additions and 124 deletions

116
lib/cli-errors.js generated
View file

@ -2,6 +2,7 @@
Object.defineProperty(exports, "__esModule", { value: true });
exports.wrapCliConfigurationError = exports.getCliConfigCategoryIfExists = exports.cliErrorsConfig = exports.CliConfigErrorCategory = exports.CommandInvocationError = void 0;
const util_1 = require("./util");
const NO_SOURCE_CODE_SEEN_DOCS_LINK = "https://gh.io/troubleshooting-code-scanning/no-source-code-seen-during-build";
/**
* A class of Error that we can classify as an error stemming from a CLI
* invocation, with associated exit code, stderr,etc.
@ -96,7 +97,11 @@ var CliConfigErrorCategory;
CliConfigErrorCategory["IncompatibleWithActionVersion"] = "IncompatibleWithActionVersion";
CliConfigErrorCategory["InitCalledTwice"] = "InitCalledTwice";
CliConfigErrorCategory["InvalidSourceRoot"] = "InvalidSourceRoot";
CliConfigErrorCategory["NoJavaScriptTypeScriptCodeFound"] = "NoJavaScriptTypeScriptCodeFound";
CliConfigErrorCategory["NoBuildCommandAutodetected"] = "NoBuildCommandAutodetected";
CliConfigErrorCategory["NoBuildMethodAutodetected"] = "NoBuildMethodAutodetected";
CliConfigErrorCategory["NoSourceCodeSeen"] = "NoSourceCodeSeen";
CliConfigErrorCategory["NoSupportedBuildCommandSucceeded"] = "NoSupportedBuildCommandSucceeded";
CliConfigErrorCategory["NoSupportedBuildSystemDetected"] = "NoSupportedBuildSystemDetected";
})(CliConfigErrorCategory || (exports.CliConfigErrorCategory = CliConfigErrorCategory = {}));
/**
* All of our caught CLI error messages that we handle specially: ie. if we
@ -105,38 +110,65 @@ var CliConfigErrorCategory;
exports.cliErrorsConfig = {
// Version of CodeQL CLI is incompatible with this version of the CodeQL Action
[CliConfigErrorCategory.IncompatibleWithActionVersion]: {
cliErrorMessageSnippets: ["is not compatible with this CodeQL CLI"],
cliErrorMessageCandidates: [
new RegExp("is not compatible with this CodeQL CLI"),
],
},
[CliConfigErrorCategory.InitCalledTwice]: {
cliErrorMessageSnippets: [
"Refusing to create databases",
"exists and is not an empty directory",
cliErrorMessageCandidates: [
new RegExp("Refusing to create databases .* but could not process any of it"),
],
additionalErrorMessageToPrepend: `Is the "init" action called twice in the same job?`,
additionalErrorMessageToAppend: `Is the "init" action called twice in the same job?`,
},
// Expected source location for database creation does not exist
[CliConfigErrorCategory.InvalidSourceRoot]: {
cliErrorMessageSnippets: ["Invalid source root"],
cliErrorMessageCandidates: [new RegExp("Invalid source root")],
},
/**
* Earlier versions of the JavaScript extractor (pre-CodeQL 2.12.0) extract externs even if no
* source code was found. This means that we don't get the no code found error from
* `codeql database finalize`. To ensure users get a good error message, we detect this manually
* here, and upon detection override the error message.
*
* This can be removed once support for CodeQL 2.11.6 is removed.
*/
[CliConfigErrorCategory.NoJavaScriptTypeScriptCodeFound]: {
[CliConfigErrorCategory.NoBuildCommandAutodetected]: {
cliErrorMessageCandidates: [
new RegExp("Could not auto-detect a suitable build method"),
],
},
[CliConfigErrorCategory.NoBuildMethodAutodetected]: {
cliErrorMessageCandidates: [
new RegExp("Could not detect a suitable build command for the source checkout"),
],
},
// Usually when a manual build script has failed, or if an autodetected language
// was unintended to have CodeQL analysis run on it.
[CliConfigErrorCategory.NoSourceCodeSeen]: {
exitCode: 32,
cliErrorMessageSnippets: ["No JavaScript or TypeScript code found."],
additionalErrorMessageToPrepend: "No code found during the build. Please see: " +
"https://gh.io/troubleshooting-code-scanning/no-source-code-seen-during-build.",
cliErrorMessageCandidates: [
new RegExp("CodeQL detected code written in .* but could not process any of it"),
new RegExp("CodeQL did not detect any code written in languages supported by CodeQL"),
/**
* Earlier versions of the JavaScript extractor (pre-CodeQL 2.12.0) extract externs even if no
* source code was found. This means that we don't get the no code found error from
* `codeql database finalize`. To ensure users get a good error message, we detect this manually
* here, and upon detection override the error message.
*
* This can be removed once support for CodeQL 2.11.6 is removed.
*/
new RegExp("No JavaScript or TypeScript code found"),
],
},
[CliConfigErrorCategory.NoSupportedBuildCommandSucceeded]: {
cliErrorMessageCandidates: [
new RegExp("No supported build command succeeded"),
],
},
[CliConfigErrorCategory.NoSupportedBuildSystemDetected]: {
cliErrorMessageCandidates: [
new RegExp("No supported build system detected"),
],
},
};
// Check if the given CLI error or exit code, if applicable, apply to any known
// CLI errors in the configuration record. If either the CLI error message matches all of
// the error messages in the config record, or the exit codes match, return the error category;
// if not, return undefined.
/**
* Check if the given CLI error or exit code, if applicable, apply to any known
* CLI errors in the configuration record. If either the CLI error message matches one of
* the error messages in the config record, or the exit codes match, return the error category;
* if not, return undefined.
*/
function getCliConfigCategoryIfExists(cliError) {
for (const [category, configuration] of Object.entries(exports.cliErrorsConfig)) {
if (cliError.exitCode !== undefined &&
@ -144,22 +176,29 @@ function getCliConfigCategoryIfExists(cliError) {
cliError.exitCode === configuration.exitCode) {
return category;
}
let allMessageSnippetsFound = true;
for (const e of configuration.cliErrorMessageSnippets) {
if (!cliError.message.includes(e) && !cliError.stderr.includes(e)) {
allMessageSnippetsFound = false;
for (const e of configuration.cliErrorMessageCandidates) {
if (cliError.message.match(e) || cliError.stderr.match(e)) {
return category;
}
}
if (allMessageSnippetsFound === true) {
return category;
}
}
return undefined;
}
exports.getCliConfigCategoryIfExists = getCliConfigCategoryIfExists;
/**
* Prepend a clearer error message with the docs link if the error message does not already
* include it. Can be removed once support for CodeQL 2.11.6 is removed; at that point, all runs
* should already include the doc link.
*/
function prependDocsLinkIfApplicable(cliErrorMessage) {
if (!cliErrorMessage.includes(NO_SOURCE_CODE_SEEN_DOCS_LINK)) {
return `No code found during the build. Please see: ${NO_SOURCE_CODE_SEEN_DOCS_LINK}. Detailed error: ${cliErrorMessage}`;
}
return cliErrorMessage;
}
/**
* Changes an error received from the CLI to a ConfigurationError with optionally an extra
* error message prepended, if it exists in a known set of configuration errors. Otherwise,
* error message appended, if it exists in a known set of configuration errors. Otherwise,
* simply returns the original error.
*/
function wrapCliConfigurationError(cliError) {
@ -170,10 +209,17 @@ function wrapCliConfigurationError(cliError) {
if (cliConfigErrorCategory === undefined) {
return cliError;
}
const errorMessageWrapperIfExists = exports.cliErrorsConfig[cliConfigErrorCategory].additionalErrorMessageToPrepend;
return errorMessageWrapperIfExists
? new util_1.ConfigurationError(`${errorMessageWrapperIfExists} ${cliError.message}`)
: new util_1.ConfigurationError(cliError.message);
let errorMessageBuilder = cliError.message;
// Can be removed once support for CodeQL 2.11.6 is removed; at that point, all runs should
// already include the doc link.
if (cliConfigErrorCategory === CliConfigErrorCategory.NoSourceCodeSeen) {
errorMessageBuilder = prependDocsLinkIfApplicable(errorMessageBuilder);
}
const additionalErrorMessageToAppend = exports.cliErrorsConfig[cliConfigErrorCategory].additionalErrorMessageToAppend;
if (additionalErrorMessageToAppend !== undefined) {
errorMessageBuilder = `${errorMessageBuilder} ${additionalErrorMessageToAppend}`;
}
return new util_1.ConfigurationError(errorMessageBuilder);
}
exports.wrapCliConfigurationError = wrapCliConfigurationError;
//# sourceMappingURL=cli-errors.js.map