Refactor configuration errors (#2105)
Refactor the existing classes of configuration errors into their own file; consolidate the place we check for configuration errors into `codeql.ts`, where the actual command invocations happen. Also, rename the `UserError` type to `ConfigurationError` to standardize on a single term.
This commit is contained in:
parent
fc9f9e5ef9
commit
1515e2bb20
54 changed files with 654 additions and 502 deletions
|
|
@ -15,7 +15,7 @@ import {
|
|||
codeQlVersionAbove,
|
||||
GitHubVersion,
|
||||
prettyPrintPack,
|
||||
UserError,
|
||||
ConfigurationError,
|
||||
} from "./util";
|
||||
|
||||
// Property names from the user-supplied config file.
|
||||
|
|
@ -332,7 +332,7 @@ export async function getLanguages(
|
|||
// If the languages parameter was not given and no languages were
|
||||
// detected then fail here as this is a workflow configuration error.
|
||||
if (languages.length === 0) {
|
||||
throw new UserError(getNoLanguagesError());
|
||||
throw new ConfigurationError(getNoLanguagesError());
|
||||
}
|
||||
|
||||
// Make sure they are supported
|
||||
|
|
@ -350,7 +350,7 @@ export async function getLanguages(
|
|||
// Any unknown languages here would have come directly from the input
|
||||
// since we filter unknown languages coming from the GitHub API.
|
||||
if (unknownLanguages.length > 0) {
|
||||
throw new UserError(getUnknownLanguagesError(unknownLanguages));
|
||||
throw new ConfigurationError(getUnknownLanguagesError(unknownLanguages));
|
||||
}
|
||||
|
||||
return parsedLanguages;
|
||||
|
|
@ -631,7 +631,7 @@ function parseQueriesFromInput(
|
|||
? rawQueriesInput.trim().slice(1).trim()
|
||||
: rawQueriesInput?.trim() ?? "";
|
||||
if (queriesInputCombines && trimmedInput.length === 0) {
|
||||
throw new UserError(
|
||||
throw new ConfigurationError(
|
||||
getConfigFilePropertyError(
|
||||
undefined,
|
||||
"queries",
|
||||
|
|
@ -664,11 +664,11 @@ export function parsePacksFromInput(
|
|||
}
|
||||
|
||||
if (languages.length > 1) {
|
||||
throw new UserError(
|
||||
throw new ConfigurationError(
|
||||
"Cannot specify a 'packs' input in a multi-language analysis. Use a codeql-config.yml file instead and specify packs by language.",
|
||||
);
|
||||
} else if (languages.length === 0) {
|
||||
throw new UserError(
|
||||
throw new ConfigurationError(
|
||||
"No languages specified. Cannot process the packs input.",
|
||||
);
|
||||
}
|
||||
|
|
@ -677,7 +677,7 @@ export function parsePacksFromInput(
|
|||
if (packsInputCombines) {
|
||||
rawPacksInput = rawPacksInput.trim().substring(1).trim();
|
||||
if (!rawPacksInput) {
|
||||
throw new UserError(
|
||||
throw new ConfigurationError(
|
||||
getConfigFilePropertyError(
|
||||
undefined,
|
||||
"packs",
|
||||
|
|
@ -715,7 +715,7 @@ export function parsePacksFromInput(
|
|||
*/
|
||||
export function parsePacksSpecification(packStr: string): Pack {
|
||||
if (typeof packStr !== "string") {
|
||||
throw new UserError(getPacksStrInvalid(packStr));
|
||||
throw new ConfigurationError(getPacksStrInvalid(packStr));
|
||||
}
|
||||
|
||||
packStr = packStr.trim();
|
||||
|
|
@ -743,14 +743,14 @@ export function parsePacksSpecification(packStr: string): Pack {
|
|||
: undefined;
|
||||
|
||||
if (!PACK_IDENTIFIER_PATTERN.test(packName)) {
|
||||
throw new UserError(getPacksStrInvalid(packStr));
|
||||
throw new ConfigurationError(getPacksStrInvalid(packStr));
|
||||
}
|
||||
if (version) {
|
||||
try {
|
||||
new semver.Range(version);
|
||||
} catch (e) {
|
||||
// The range string is invalid. OK to ignore the caught error
|
||||
throw new UserError(getPacksStrInvalid(packStr));
|
||||
throw new ConfigurationError(getPacksStrInvalid(packStr));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -764,12 +764,12 @@ export function parsePacksSpecification(packStr: string): Pack {
|
|||
path.normalize(packPath).split(path.sep).join("/") !==
|
||||
packPath.split(path.sep).join("/"))
|
||||
) {
|
||||
throw new UserError(getPacksStrInvalid(packStr));
|
||||
throw new ConfigurationError(getPacksStrInvalid(packStr));
|
||||
}
|
||||
|
||||
if (!packPath && pathStart) {
|
||||
// 0 length path
|
||||
throw new UserError(getPacksStrInvalid(packStr));
|
||||
throw new ConfigurationError(getPacksStrInvalid(packStr));
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
@ -852,7 +852,9 @@ function parseRegistries(
|
|||
? (yaml.load(registriesInput) as RegistryConfigWithCredentials[])
|
||||
: undefined;
|
||||
} catch (e) {
|
||||
throw new UserError("Invalid registries input. Must be a YAML string.");
|
||||
throw new ConfigurationError(
|
||||
"Invalid registries input. Must be a YAML string.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -868,12 +870,16 @@ function isLocal(configPath: string): boolean {
|
|||
function getLocalConfig(configFile: string, workspacePath: string): UserConfig {
|
||||
// Error if the config file is now outside of the workspace
|
||||
if (!(configFile + path.sep).startsWith(workspacePath + path.sep)) {
|
||||
throw new UserError(getConfigFileOutsideWorkspaceErrorMessage(configFile));
|
||||
throw new ConfigurationError(
|
||||
getConfigFileOutsideWorkspaceErrorMessage(configFile),
|
||||
);
|
||||
}
|
||||
|
||||
// Error if the file does not exist
|
||||
if (!fs.existsSync(configFile)) {
|
||||
throw new UserError(getConfigFileDoesNotExistErrorMessage(configFile));
|
||||
throw new ConfigurationError(
|
||||
getConfigFileDoesNotExistErrorMessage(configFile),
|
||||
);
|
||||
}
|
||||
|
||||
return yaml.load(fs.readFileSync(configFile, "utf8")) as UserConfig;
|
||||
|
|
@ -890,7 +896,9 @@ async function getRemoteConfig(
|
|||
const pieces = format.exec(configFile);
|
||||
// 5 = 4 groups + the whole expression
|
||||
if (pieces === null || pieces.groups === undefined || pieces.length < 5) {
|
||||
throw new UserError(getConfigFileRepoFormatInvalidMessage(configFile));
|
||||
throw new ConfigurationError(
|
||||
getConfigFileRepoFormatInvalidMessage(configFile),
|
||||
);
|
||||
}
|
||||
|
||||
const response = await api
|
||||
|
|
@ -906,9 +914,11 @@ async function getRemoteConfig(
|
|||
if ("content" in response.data && response.data.content !== undefined) {
|
||||
fileContents = response.data.content;
|
||||
} else if (Array.isArray(response.data)) {
|
||||
throw new UserError(getConfigFileDirectoryGivenMessage(configFile));
|
||||
throw new ConfigurationError(
|
||||
getConfigFileDirectoryGivenMessage(configFile),
|
||||
);
|
||||
} else {
|
||||
throw new UserError(getConfigFileFormatInvalidMessage(configFile));
|
||||
throw new ConfigurationError(getConfigFileFormatInvalidMessage(configFile));
|
||||
}
|
||||
|
||||
return yaml.load(
|
||||
|
|
@ -1008,7 +1018,7 @@ function createRegistriesBlock(registries: RegistryConfigWithCredentials[]): {
|
|||
!Array.isArray(registries) ||
|
||||
registries.some((r) => !r.url || !r.packages)
|
||||
) {
|
||||
throw new UserError(
|
||||
throw new ConfigurationError(
|
||||
"Invalid 'registries' input. Must be an array of objects with 'url' and 'packages' properties.",
|
||||
);
|
||||
}
|
||||
|
|
@ -1071,7 +1081,7 @@ function validateBuildModeInput(
|
|||
}
|
||||
|
||||
if (!Object.values(BuildMode).includes(buildModeInput as BuildMode)) {
|
||||
throw new UserError(
|
||||
throw new ConfigurationError(
|
||||
`Invalid build mode: '${buildModeInput}'. Supported build modes are: ${Object.values(
|
||||
BuildMode,
|
||||
).join(", ")}.`,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue