Skip to content

Commit

Permalink
fix #1774, improve access errors and warn when sudo is used
Browse files Browse the repository at this point in the history
  • Loading branch information
davidfirst committed Jul 30, 2019
1 parent f36b898 commit dd83e35
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 6 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [unreleased]

- [#1774](https://github.com/teambit/bit/issues/1774) improve access errors and warn when sudo is used

## [14.2.4-dev.1] - 2019-07-30

- do not delete trackDir when a component is imported
Expand Down
15 changes: 13 additions & 2 deletions bin/bit.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const constants = require('../dist/constants');

const MINIMUM_NODE_VERSION = '8.12.0';

// set max listeners to a more appripriate numbers
// set max listeners to a more appropriate numbers
require('events').EventEmitter.defaultMaxListeners = 100;
require('regenerator-runtime/runtime');

Expand All @@ -21,18 +21,29 @@ const chalk = require('chalk');
const nodeVersion = process.versions.node.split('-')[0];
const compatibilityStatus = getCompatibilityStatus();

warnIfRunningAsRoot();

function ensureDirectories() {
mkdirp.sync(constants.GLOBAL_CONFIG);
mkdirp.sync(constants.GLOBAL_LOGS);
}

function warnIfRunningAsRoot() {
const isRoot = process.getuid && process.getuid() === 0;
if (isRoot) {
// eslint-disable-next-line
console.log(chalk.red('Warning: running bit as root might cause permission issues later'));
}
}

function verifyCompatibility() {
if (compatibilityStatus === 'unsupported') {
console.log(
// eslint-disable-line
require('chalk').red(
`Node version ${nodeVersion} is not supported, please use Node.js ${MINIMUM_NODE_VERSION} or higher. If you must use legacy versions of Node.js, please use our binary installation methods. https://docs.bit.dev/docs/installation.html`
)
); // eslint-disable-line
);
return process.exit();
}

Expand Down
26 changes: 26 additions & 0 deletions e2e/flows/permissions-errors.e2e.3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { expect } from 'chai';
import Helper from '../e2e-helper';

describe('permissions', function () {
this.timeout(0);
const helper = new Helper();
after(() => {
helper.destroyEnv();
});
describe('adding a component with sudo', () => {
before(() => {
helper.reInitLocalScope();
helper.createComponentBarFoo();
const output = helper.runCmd('sudo bit add bar/foo.js');
expect(output).to.have.string('Warning');
expect(output).to.have.string('root');
});
describe('tagging the same component without sudo', () => {
it('should show a descriptive error', () => {
const output = helper.runWithTryCatch('bit tag -a');
expect(output).to.have.string('error: you do not have permissions to access');
expect(output).to.have.string('were you running bit, npm or git as root');
});
});
});
});
19 changes: 15 additions & 4 deletions src/cli/default-error-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -608,19 +608,30 @@ function getExternalErrorsMessageAndStack(errors: Error[]): string {
* reason why we don't check (err instanceof AbstractError) is that it could be thrown from a fork,
* in which case, it loses its class and has only the fields.
*/
function sendToAnalyticsAndSentry(err) {
function sendToAnalyticsAndSentry(err: Error) {
const possiblyHashedError = hashErrorIfNeeded(err);
// only level FATAL are reported to Sentry.
// $FlowFixMe
const level = err.isUserError ? LEVEL.INFO : LEVEL.FATAL;
const shouldNotReportToSentry = Boolean(err.isUserError || err.code === 'EACCES');
// only level FATAL are reported to Sentry.
const level = shouldNotReportToSentry ? LEVEL.INFO : LEVEL.FATAL;
Analytics.setError(level, possiblyHashedError);
}

function handleNonBitCustomErrors(err: Error): string {
if (err.code === 'EACCES') {
// see #1774
return chalk.red(
`error: you do not have permissions to access '${err.path}', were you running bit, npm or git as root?`
);
}
return chalk.red(err.message || err);
}

export default (err: Error): ?string => {
const errorDefinition = findErrorDefinition(err);
sendToAnalyticsAndSentry(err);
if (!errorDefinition) {
return chalk.red(err.message || err);
return handleNonBitCustomErrors(err);
}
const func = getErrorFunc(errorDefinition);
const errorMessage = getErrorMessage(err, func) || 'unknown error';
Expand Down

0 comments on commit dd83e35

Please sign in to comment.