Skip to content

Commit

Permalink
fix(CLI): Fix handling when local serverless is removed in command run
Browse files Browse the repository at this point in the history
  • Loading branch information
medikoo committed Sep 28, 2021
1 parent 54af908 commit 1a3ccdb
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 33 deletions.
74 changes: 41 additions & 33 deletions lib/cli/handle-error.js
Expand Up @@ -8,8 +8,8 @@ const sfeVersion = require('@serverless/dashboard-plugin/package.json').version;
const { platformClientVersion } = require('@serverless/dashboard-plugin');
const { style, writeText, legacy } = require('@serverless/utils/log');
const slsVersion = require('./../../package').version;
const { logWarning } = require('../classes/Error');
const isStandaloneExecutable = require('../utils/isStandaloneExecutable');
const ServerlessError = require('../serverless-error');
const tokenizeException = require('../utils/tokenize-exception');
const logDeprecation = require('../utils/logDeprecation');
const resolveIsLocallyInstalled = require('../utils/is-locally-installed');
Expand Down Expand Up @@ -65,40 +65,48 @@ module.exports = async (exception, options = {}) => {
if (isInvokedByGlobalInstallation && !resolveIsLocallyInstalled()) {
const localServerlessPath = resolveLocalServerlessPath();

try {
// Attempt to use error handler from local version
// TODO: Remove local version fallback with next major (when its moved to the top of the process)
const localErrorHandlerData = (() => {
try {
require(path.resolve(localServerlessPath, 'lib/cli/handle-error'))(exception, {
serverless,
isLocallyInstalled,
isUncaughtException,
command,
options: cliOptions,
commandSchema,
serviceDir,
configuration,
hasTelemetryBeenReported,
commandUsage,
variableSourcesInConfig,
});
return;
} catch (error) {
// Pass and attempt to use old-style error handler from local version

// Ugly mock of serverless below is used to ensure that Framework version will be logged with `(local)` suffix
require(path.resolve(localServerlessPath, 'lib/classes/Error')).logError(exception, {
serverless: serverless || { isLocallyInstalled },
forceExit: isUncaughtException,
});
return;
return {
handle: require.resolve(path.resolve(localServerlessPath, 'lib/cli/handle-error')),
options: {
serverless,
isLocallyInstalled,
isUncaughtException,
command,
options: cliOptions,
commandSchema,
serviceDir,
configuration,
hasTelemetryBeenReported,
commandUsage,
variableSourcesInConfig,
},
};
} catch {
try {
// Ugly mock of serverless below is used to ensure that Framework version will be logged with `(local)` suffix
return {
handle: require.resolve(path.resolve(localServerlessPath, 'lib/classes/Error'))
.logError,
options: {
serverless: serverless || { isLocallyInstalled },
forceExit: isUncaughtException,
},
};
} catch {
// Corner case of local installation being removed during command processing.
// It can happen e.g. during "plugin uninstall" command, where "serverless" originally
// installed a as peer dependency was removed
logWarning('Could not resolve path to locally installed error handler');
return null;
}
}
} catch (err) {
// This is just a fallback as for most (all?) versions it shouldn't happen
throw new ServerlessError(
'Could not resolve path to locally installed error handler.',
'INVALID_LOCAL_SERVERLESS_ERROR_HANDLER'
);
})();

if (localErrorHandlerData) {
localErrorHandlerData.handle(exception, localErrorHandlerData.options);
return;
}
}

Expand Down
11 changes: 11 additions & 0 deletions lib/utils/telemetry/generatePayload.js
Expand Up @@ -197,6 +197,17 @@ module.exports = ({
};
}
const localServerlessPath = resolveLocalServerlessPath();
try {
require.resolve(path.resolve(localServerlessPath, 'package.json'));
} catch {
// Corner case of local installation being removed during command processing.
// It can happen e.g. during "plugin uninstall" command, where "serverless" originally
// installed a as peer dependency was removed
return {
'serverless': require('../../../package').version,
'@serverless/dashboard-plugin': require('@serverless/dashboard-plugin/package').version,
};
}
return {
'serverless': require(path.resolve(localServerlessPath, 'package.json')).version,
// Since v2.42.0 it's "@serverless/dashboard-plugin"
Expand Down

0 comments on commit 1a3ccdb

Please sign in to comment.