Browse Source

implement this.error

gh-1187
Rich Harris 8 years ago
parent
commit
7831164748
  1. 75
      src/utils/transform.js
  2. 0
      test/function/plugin-error-only-first-transform-bundle/_config.js
  3. 0
      test/function/plugin-error-only-first-transform-bundle/main.js
  4. 4
      test/function/plugin-error-only-first-transform/_config.js
  5. 0
      test/function/plugin-error-only-first-transform/main.js
  6. 29
      test/function/plugin-error/_config.js
  7. 1
      test/function/plugin-error/main.js
  8. 22
      test/function/report-transform-error-file/_config.js
  9. 3
      test/function/report-transform-error-file/foo.js
  10. 3
      test/function/report-transform-error-file/main.js

75
src/utils/transform.js

@ -1,7 +1,6 @@
import { decode } from 'sourcemap-codec';
import { locate } from 'locate-character';
import error from './error.js';
import relativeId from './relativeId.js';
import getCodeFrame from './getCodeFrame.js';
export default function transform ( bundle, source, id, plugins ) {
@ -15,33 +14,56 @@ export default function transform ( bundle, source, id, plugins ) {
const originalCode = source.code;
let ast = source.ast;
let errored = false;
return plugins.reduce( ( promise, plugin ) => {
return promise.then( previous => {
if ( !plugin.transform ) return previous;
let promise = Promise.resolve( source.code );
const context = {
warn: ( warning, pos ) => {
if ( typeof warning === 'string' ) {
warning = { message: warning };
plugins.forEach( plugin => {
if ( !plugin.transform ) return;
promise = promise.then( previous => {
function augment ( object, pos, code ) {
if ( typeof object === 'string' ) {
object = { message: object };
}
warning.plugin = plugin.name;
if ( !warning.code ) warning.code = 'PLUGIN_WARNING';
if ( !object.code ) object.code = code;
if ( pos !== undefined ) {
warning.pos = pos;
object.pos = pos;
const { line, column } = locate( previous, pos, { offsetLine: 1 });
warning.loc = { file: id, line, column };
warning.frame = getCodeFrame( previous, line, column );
object.loc = { file: id, line, column };
object.frame = getCodeFrame( previous, line, column );
}
return object;
}
let err;
const context = {
warn: ( warning, pos ) => {
warning = augment( warning, pos, 'PLUGIN_WARNING' );
warning.plugin = plugin.name;
bundle.warn( warning );
},
error ( e, pos ) {
err = augment( e, pos, 'PLUGIN_ERROR' );
}
};
return Promise.resolve( plugin.transform.call( context, previous, id ) ).then( result => {
let transformed;
try {
transformed = plugin.transform.call( context, previous, id );
} catch ( err ) {
context.error( err );
}
return Promise.resolve( transformed )
.then( result => {
if ( err ) throw err;
if ( result == null ) return previous;
if ( typeof result === 'string' ) {
@ -65,23 +87,14 @@ export default function transform ( bundle, source, id, plugins ) {
ast = result.ast;
return result.code;
});
}).catch( err => {
// TODO this all seems a bit hacky
if ( errored ) throw err;
errored = true;
})
.catch( err => {
err.plugin = plugin.name;
throw err;
err.id = id;
error( err );
});
}, Promise.resolve( source.code ) )
.catch( err => {
error({
code: 'BAD_TRANSFORMER',
message: `Error transforming ${relativeId( id )}${err.plugin ? ` with '${err.plugin}' plugin` : ''}: ${err.message}`,
plugin: err.plugin,
id
});
})
.then( code => ({ code, originalCode, originalSourceMap, ast, sourceMapChain }) );
});
return promise.then( code => ({ code, originalCode, originalSourceMap, ast, sourceMapChain }) );
}

0
test/function/throws-only-first-transform-bundle/_config.js → test/function/plugin-error-only-first-transform-bundle/_config.js

0
test/function/throws-only-first-transform-bundle/main.js → test/function/plugin-error-only-first-transform-bundle/main.js

4
test/function/throws-only-first-transform/_config.js → test/function/plugin-error-only-first-transform/_config.js

@ -20,8 +20,8 @@ module.exports = {
]
},
error: {
code: 'BAD_TRANSFORMER',
message: `Error transforming main.js with 'plugin1' plugin: Something happened 1`,
code: 'PLUGIN_ERROR',
message: `Something happened 1`,
plugin: 'plugin1',
id: path.resolve( __dirname, 'main.js' )
}

0
test/function/throws-only-first-transform/main.js → test/function/plugin-error-only-first-transform/main.js

29
test/function/plugin-error/_config.js

@ -0,0 +1,29 @@
const path = require( 'path' );
module.exports = {
description: 'plugin transform hooks can use `this.error({...}, char)` (#1140)',
options: {
plugins: [{
name: 'test',
transform ( code, id ) {
this.error( 'nope', 22 );
}
}]
},
error: {
code: 'PLUGIN_ERROR',
plugin: 'test',
message: 'nope',
id: path.resolve( __dirname, 'main.js' ),
pos: 22,
loc: {
file: path.resolve( __dirname, 'main.js' ),
line: 1,
column: 22
},
frame: `
1: assert.equal( 21 * 2, TK );
^
`
}
};

1
test/function/plugin-error/main.js

@ -0,0 +1 @@
assert.equal( 21 * 2, TK );

22
test/function/report-transform-error-file/_config.js

@ -1,22 +0,0 @@
var path = require( 'path' );
var assert = require( 'assert' );
module.exports = {
description: 'reports which file caused a transform error',
options: {
plugins: [{
name: 'bad-plugin',
transform: function ( code, id ) {
if ( /foo/.test( id ) ) {
throw new Error( 'nope' );
}
}
}]
},
error: {
code: 'BAD_TRANSFORMER',
message: `Error transforming foo.js with 'bad-plugin' plugin: nope`,
plugin: 'bad-plugin',
id: path.resolve( __dirname, 'foo.js' )
}
};

3
test/function/report-transform-error-file/foo.js

@ -1,3 +0,0 @@
export default function () {
console.log( 'foo' );
}

3
test/function/report-transform-error-file/main.js

@ -1,3 +0,0 @@
import foo from './foo.js';
foo();
Loading…
Cancel
Save