Skip to content

Use dedicated Error class from the Framework #649

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 22 additions & 14 deletions lib/docker.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const path = require('path');
* @param {string[]} options
* @return {Object}
*/
async function dockerCommand(options) {
async function dockerCommand(options, pluginInstance) {
const cmd = 'docker';
try {
return await spawn(cmd, options, { encoding: 'utf-8' });
Expand All @@ -17,7 +17,10 @@ async function dockerCommand(options) {
e.stderrBuffer &&
e.stderrBuffer.toString().includes('command not found')
) {
throw new Error('docker not found! Please install it.');
throw new pluginInstance.serverless.classes.Error(
'docker not found! Please install it.',
'PYTHON_REQUIREMENTS_DOCKER_NOT_FOUND'
);
}
throw e;
}
Expand All @@ -29,19 +32,22 @@ async function dockerCommand(options) {
* @param {string[]} extraArgs
* @return {string} The name of the built docker image.
*/
async function buildImage(dockerFile, extraArgs) {
async function buildImage(dockerFile, extraArgs, pluginInstance) {
const imageName = 'sls-py-reqs-custom';
const options = ['build', '-f', dockerFile, '-t', imageName];

if (Array.isArray(extraArgs)) {
options.push(...extraArgs);
} else {
throw new Error('dockerRunCmdExtraArgs option must be an array');
throw new pluginInstance.serverless.classes.Error(
'dockerRunCmdExtraArgs option must be an array',
'PYTHON_REQUIREMENTS_INVALID_DOCKER_EXTRA_ARGS'
);
}

options.push('.');

await dockerCommand(options);
await dockerCommand(options, pluginInstance);
return imageName;
}

Expand All @@ -50,7 +56,7 @@ async function buildImage(dockerFile, extraArgs) {
* @param {string} servicePath
* @return {string} file name
*/
function findTestFile(servicePath) {
function findTestFile(servicePath, pluginInstance) {
if (fse.pathExistsSync(path.join(servicePath, 'serverless.yml'))) {
return 'serverless.yml';
}
Expand All @@ -63,8 +69,9 @@ function findTestFile(servicePath) {
if (fse.pathExistsSync(path.join(servicePath, 'requirements.txt'))) {
return 'requirements.txt';
}
throw new Error(
'Unable to find serverless.{yml|yaml|json} or requirements.txt for getBindPath()'
throw new pluginInstance.serverless.classes.Error(
'Unable to find serverless.{yml|yaml|json} or requirements.txt for getBindPath()',
'PYTHON_REQUIREMENTS_MISSING_GET_BIND_PATH_FILE'
);
}

Expand All @@ -73,7 +80,8 @@ function findTestFile(servicePath) {
* @param {string} bindPath
* @return {boolean}
*/
async function tryBindPath(bindPath, testFile, { serverless, log }) {
async function tryBindPath(bindPath, testFile, pluginInstance) {
const { serverless, log } = pluginInstance;
const debug = process.env.SLS_DEBUG;
const options = [
'run',
Expand All @@ -92,7 +100,7 @@ async function tryBindPath(bindPath, testFile, { serverless, log }) {
serverless.cli.log(`Trying bindPath ${bindPath} (${options})`);
}
}
const ps = await dockerCommand(options);
const ps = await dockerCommand(options, pluginInstance);
if (debug) {
if (log) {
log.debug(ps.stdoutBuffer.trim());
Expand Down Expand Up @@ -126,7 +134,7 @@ async function getBindPath(servicePath, pluginInstance) {
}

// test docker is available
await dockerCommand(['version']);
await dockerCommand(['version'], pluginInstance);

// find good bind path for Windows
let bindPaths = [];
Expand Down Expand Up @@ -159,7 +167,7 @@ async function getBindPath(servicePath, pluginInstance) {
bindPaths.push(`/mnt/${drive.toUpperCase()}/${path}`);
bindPaths.push(`${drive.toUpperCase()}:/${path}`);

const testFile = findTestFile(servicePath);
const testFile = findTestFile(servicePath, pluginInstance);

for (let i = 0; i < bindPaths.length; i++) {
const bindPath = bindPaths[i];
Expand All @@ -176,7 +184,7 @@ async function getBindPath(servicePath, pluginInstance) {
* @param {string} bindPath
* @return {boolean}
*/
async function getDockerUid(bindPath) {
async function getDockerUid(bindPath, pluginInstance) {
const options = [
'run',
'--rm',
Expand All @@ -188,7 +196,7 @@ async function getDockerUid(bindPath) {
'%u',
'/bin/sh',
];
const ps = await dockerCommand(options);
const ps = await dockerCommand(options, pluginInstance);
return ps.stdoutBuffer.trim();
}

Expand Down
31 changes: 20 additions & 11 deletions lib/pip.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ function generateRequirementsFile(
}
}

async function pipAcceptsSystem(pythonBin) {
async function pipAcceptsSystem(pythonBin, pluginInstance) {
// Check if pip has Debian's --system option and set it if so
try {
const pipTestRes = await spawn(pythonBin, ['-m', 'pip', 'help', 'install']);
Expand All @@ -120,7 +120,10 @@ async function pipAcceptsSystem(pythonBin) {
e.stderrBuffer &&
e.stderrBuffer.toString().includes('command not found')
) {
throw new Error(`${pythonBin} not found! Try the pythonBin option.`);
throw new pluginInstance.serverless.classes.Error(
`${pythonBin} not found! Install it according to the poetry docs.`,
'PYTHON_REQUIREMENTS_PYTHON_NOT_FOUND'
);
}
throw e;
}
Expand Down Expand Up @@ -167,10 +170,9 @@ async function installRequirements(targetFolder, pluginInstance) {
// Check if we're using the legacy --cache-dir command...
if (options.pipCmdExtraArgs.indexOf('--cache-dir') > -1) {
if (options.dockerizePip) {
throw (
'Error: You can not use --cache-dir with Docker any more, please\n' +
' use the new option useDownloadCache instead. Please see:\n' +
' https://github.com/UnitedIncome/serverless-python-requirements#caching'
throw new pluginInstance.serverless.classes.Error(
'You cannot use --cache-dir with Docker any more, please use the new option useDownloadCache instead. Please see: https://github.com/UnitedIncome/serverless-python-requirements#caching for more details.',
'PYTHON_REQUIREMENTS_CACHE_DIR_DOCKER_INVALID'
);
} else {
if (log) {
Expand Down Expand Up @@ -222,7 +224,7 @@ async function installRequirements(targetFolder, pluginInstance) {
pipCmd.push('--cache-dir', downloadCacheDir);
}

if (await pipAcceptsSystem(options.pythonBin)) {
if (await pipAcceptsSystem(options.pythonBin, pluginInstance)) {
pipCmd.push('--system');
}
}
Expand Down Expand Up @@ -251,7 +253,8 @@ async function installRequirements(targetFolder, pluginInstance) {
try {
dockerImage = await buildImage(
options.dockerFile,
options.dockerBuildCmdExtraArgs
options.dockerBuildCmdExtraArgs,
pluginInstance
);
} finally {
buildDockerImageProgress && buildDockerImageProgress.remove();
Expand Down Expand Up @@ -335,7 +338,7 @@ async function installRequirements(targetFolder, pluginInstance) {
]);
} else {
// Use same user so --cache-dir works
dockerCmd.push('-u', await getDockerUid(bindPath));
dockerCmd.push('-u', await getDockerUid(bindPath, pluginInstance));
}

for (let path of options.dockerExtraFiles) {
Expand All @@ -357,7 +360,10 @@ async function installRequirements(targetFolder, pluginInstance) {
if (Array.isArray(options.dockerRunCmdExtraArgs)) {
dockerCmd.push(...options.dockerRunCmdExtraArgs);
} else {
throw new Error('dockerRunCmdExtraArgs option must be an array');
throw new pluginInstance.serverless.classes.Error(
'dockerRunCmdExtraArgs option must be an array',
'PYTHON_REQUIREMENTS_INVALID_DOCKER_EXTRA_ARGS'
);
}

dockerCmd.push(dockerImage);
Expand Down Expand Up @@ -404,7 +410,10 @@ async function installRequirements(targetFolder, pluginInstance) {
cmd.indexOf('python') > -1
? 'Try the pythonBin option'
: 'Please install it';
throw new Error(`${cmd} not found! ${advice}`);
throw new pluginInstance.serverless.classes.Error(
`${cmd} not found! ${advice}`,
'PYTHON_REQUIREMENTS_COMMAND_NOT_FOUND'
);
}
throw e;
}
Expand Down
5 changes: 3 additions & 2 deletions lib/pipenv.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ async function pipfileToRequirements() {
e.stderrBuffer &&
e.stderrBuffer.toString().includes('command not found')
) {
throw new Error(
`pipenv not found! Install it with 'pip install pipenv'.`
throw new this.serverless.classes.Error(
`pipenv not found! Install it according to the poetry docs.`,
'PYTHON_REQUIREMENTS_PIPENV_NOT_FOUND'
);
}
throw e;
Expand Down
5 changes: 3 additions & 2 deletions lib/poetry.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ async function pyprojectTomlToRequirements() {
e.stderrBuffer &&
e.stderrBuffer.toString().includes('command not found')
) {
throw new Error(
`poetry not found! Install it according to the poetry docs.`
throw new this.serverless.classes.Error(
`poetry not found! Install it according to the poetry docs.`,
'PYTHON_REQUIREMENTS_POETRY_NOT_FOUND'
);
}
throw e;
Expand Down