Skip to content
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

Add helpful plugin errors #2691

Merged
merged 3 commits into from Mar 6, 2019
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 1 addition & 2 deletions packages/core/parcel-bundler/.gitignore
Expand Up @@ -5,7 +5,6 @@ test/input
test/integration/**/elm-stuff
test/integration/**/target
test/integration/**/Cargo.lock
test/**/node_modules
test/**/yarn.lock
test/**/package-lock.json
test/integration/babel-plugin-autoinstall/package.json
test/integration/babel-plugin-autoinstall/package.json
8 changes: 7 additions & 1 deletion packages/core/parcel-bundler/src/Bundler.js
Expand Up @@ -206,17 +206,23 @@ class Bundler extends EventEmitter {
return;
}

let lastDep;
try {
let deps = Object.assign({}, pkg.dependencies, pkg.devDependencies);
for (let dep in deps) {
lastDep = dep;
const pattern = /^(@.*\/)?parcel-plugin-.+/;
if (pattern.test(dep)) {
let plugin = await localRequire(dep, relative);
await plugin(this);
}
}
} catch (err) {
logger.warn(err);
logger.warn(
`Plugin ${lastDep} failed to initialize: ${err.stack ||
err.message ||
err}`
);
}
}

Expand Down
17 changes: 16 additions & 1 deletion packages/core/parcel-bundler/src/Parser.js
@@ -1,4 +1,5 @@
const path = require('path');
const logger = require('@parcel/logger');
const RawAsset = require('./assets/RawAsset');
const GlobAsset = require('./assets/GlobAsset');
const {isGlob} = require('./utils/glob');
Expand Down Expand Up @@ -75,7 +76,21 @@ class Parser {
let extension = path.extname(filename).toLowerCase();
let parser = this.extensions[extension] || RawAsset;
if (typeof parser === 'string') {
parser = this.extensions[extension] = require(parser);
try {
parser = this.extensions[extension] = require(parser);
} catch (err) {
let relFilename = path.relative(process.cwd(), filename);
let relParserName = path.relative(process.cwd(), parser);
if (relParserName.slice(0, 12) === 'node_modules') {
relParserName = relParserName.slice(13);
}
logger.warn(
`Parser "${relParserName}" failed to initialize when processing ` +
`asset "${relFilename}". Threw the following error:\n` +
`${err.stack || err.message || err} falling back to RawAsset`
);
return RawAsset;
}
}

return parser;
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

@@ -1,5 +1,5 @@
{
"name": "parcel-test",
"name": "test-plugin-project",
"private": true,
"dependencies": {
"parcel-plugin-test": "*"
Expand Down
@@ -0,0 +1 @@
module.exports = require('./test.txt');

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

@@ -0,0 +1,7 @@
{
"name": "throwing-plugin-parser-project",
"private": true,
"dependencies": {
"parcel-plugin-test": "*"
}
}
@@ -0,0 +1 @@
hello world
@@ -0,0 +1 @@
module.exports = require('./test.txt');

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

@@ -0,0 +1,7 @@
{
"name": "throwing-plugin-project",
"private": true,
"dependencies": {
"parcel-plugin-test": "*"
}
}
@@ -0,0 +1 @@
hello world
4 changes: 2 additions & 2 deletions packages/core/parcel-bundler/test/mochareporters.json
@@ -1,6 +1,6 @@
{
"reporterEnabled": "mocha-junit-reporter",
"reporterEnabled": "spec, mocha-junit-reporter",
"mochaJunitReporterReporterOptions": {
"mochaFile": "junit-testresults.xml"
}
}
}
52 changes: 50 additions & 2 deletions packages/core/parcel-bundler/test/plugins.js
@@ -1,10 +1,14 @@
const assert = require('assert');
const sinon = require('sinon');
const path = require('path');
const logger = require('@parcel/logger');
const {bundle, run, assertBundleTree} = require('@parcel/test-utils');

describe('plugins', function() {
it('should load plugins and apply custom asset type', async function() {
let b = await bundle(path.join(__dirname, '/integration/plugins/index.js'));
let b = await bundle(
path.join(__dirname, '/integration/plugins/test-plugin/index.js')
);

await assertBundleTree(b, {
name: 'index.js',
Expand All @@ -22,7 +26,10 @@ describe('plugins', function() {

it('should load package.json from parent tree', async function() {
let b = await bundle(
path.join(__dirname, '/integration/plugins/sub-folder/index.js')
path.join(
__dirname,
'/integration/plugins/test-plugin/sub-folder/index.js'
)
);

await assertBundleTree(b, {
Expand All @@ -38,4 +45,45 @@ describe('plugins', function() {
let output = await run(b);
assert.equal(output, 'hello world');
});

it('log a warning if a plugin throws an exception during initialization', async function() {
sinon.stub(logger, 'warn');

let b = await bundle(
path.join(__dirname, '/integration/plugins/throwing-plugin/index.js')
);

await run(b);

sinon.assert.calledWith(
logger.warn,
sinon.match(
'Plugin parcel-plugin-test failed to initialize: Error: Plugin error'
)
);

logger.warn.restore();
});

it('log a warning if a parser throws an exception during initialization', async function() {
sinon.stub(logger, 'warn');

let b = await bundle(
path.join(
__dirname,
'/integration/plugins/throwing-plugin-parser/index.js'
)
);

await run(b);

sinon.assert.calledWith(
logger.warn,
sinon.match(
/Parser "test.integration.plugins.throwing-plugin-parser.node_modules.parcel-plugin-test.TextAsset\.js" failed to initialize when processing asset "test.integration.plugins.throwing-plugin-parser.test\.txt"\. Threw the following error:\nError: Parser error/
)
);

logger.warn.restore();
});
});