Gulp location of unhandled error in events.js:141 - javascript

When I run task for example using comman gulp scripts:common, I get this output:
[14:05:47] Requiring external module babel-core/register
[14:05:49] Using gulpfile /home/sites/blablabla/gulpfile.babel.js
[14:05:49] Starting 'scripts:common'...
events.js:141
throw er; // Unhandled 'error' event
^
SyntaxError: Unexpected token
Well, for SyntaxError it would be useful to know where it found that unexpected token. How to tell it to show at least file and line? Where to find that evetns.js file? Could I put console.trace() or something like that there?

I solve this problem by running jshint on my scripts:
/*
* `gulp check_scripts` - Lints script files
*/
gulp.task('check_scripts', function() {
return gulp.src([
'gulpfile.js' //, other scripts to check
])
.pipe(jshint())
.pipe(jshint.reporter('jshint-stylish'))
.pipe(gulpif(enabled.failJSHint, jshint.reporter('fail')));
});
enabled.failJSHint is there to allow errors to pass in local environment but fail in production.
This will lint any syntax errors in your scripts.
Additionally you may want to hook it to other task so it's run automatically before proper build:
gulp.task('default', ['check_scripts', 'clean'], function() {
gulp.start('build');
});
This is the general idea.

You can look at error stack trace by adding custom "on error" handler to the gulp task.
gulp.task('compile:js', function() {
return (
gulp.src(jsPath)
.pipe(yourCustomTask())
.on('error', function(err) {
console.log(err.stack);
this.end();
})
);
});

Also, as another variant, adding gulp-plumber into pipeline makes error messages more clear.

Related

See code creating Browserify errors (from fake_...js) by outputting code to console or viewing fake_.js file

I can catch errors from Browserify (as shown by other SO posts on this topic), however I need to see the specific code causing the error. Example:
Error: Parsing file /public/javascripts/lib/fake_7af951da.js:
Line 10: Spread must be the final element of an element list //<--? need details
I want to output to the console the specific code in the fake_.js file that is causing the error, or I need to be able to view the fake_.js file so that I can look at Line 10.
Here is my gulp info:
gulp.task('browserify', function() {
// Single entry point to browserify
gulp.src('./public/javascripts/lib/*.js') //lists files to require
.pipe(browserify({
insertGlobals : true,
debug : !gulp.env.production
}))
.on('error', function(err){
console.log(err.stack);
})
.pipe(gulp.dest('./public/javascripts/out.js'))
});

Gulp plumber cannot pipe to undefined

I am trying, to write a module that when gulp is watching a task, and a Less file changed with some error, it should give a message to the console, but it should not crash the system, which it does no:
This is the code I have written:
var onError = function (err) {
console.log(err);
};
gulp.task('styles', function () {
gulp.src('./{views}/**/*.{less}')
.pipe(plumber({
errorHandler: onError
}))
.pipe(less())
.pipe(gulp.dest('build/styles/common.css'));
});
When I run the above code, I get the error below:
'styles' errored after 20 ms
Error in plugin 'plumber'
Message:
Can't pipe to undefined
I have had the same error. I resolved it by adding () after the plumber. Here is the code.
Earlier Code:
gulp.task('scripts',function(){
gulp.src('admin-scripts.js')
.pipe(plumber)
.pipe(uglify().on('error', function(e){
console.log(e);
}))
.pipe(gulp.dest('build/js'));
});
Fixed Code:
gulp.task('scripts',function(){
gulp.src('admin-scripts.js')
.pipe(plumber())
.pipe(uglify().on('error', function(e){
console.log(e);
}))
.pipe(gulp.dest('build/js'));
});
I was missing the () after plumber.
Hope this helps.
Are you sure to have installed gulp-less using
npm install --save-dev
and referencing it in your gulpfile with
var less = require('gulp-less');
This error from plumber occurs when the destination of your pipe (here your less) is undefined.
Also why are you using the {} here ? They are a bit useless I think since you're targetting only one thing in it, you could remove them.
Yes I have installed gulp-less, and I figured out the solution for this problem aswell:
It should be as follow:
gulp.task('mystyle', function () {
gulp.src('build/stylesfiles.less').pipe(plumber()).pipe(less()).
pipe(gulp.dest ('build/styles/assets'));
});
Basically I do not need the Error message, it will give me a default error, which can get my job done.Using the above code will make sure it runs, and gives me my error, but not crash the server....but thank you "Apercu"

Logging with grunt and qunit

I am running javascript unittests with grunt/qunit. Sometimes the tests fails because of e.g syntax errors in the source files (works fine with file info if syntax errors are introduced in the test files). When that happens grunt simply prints the line number and not the file where the problem is.
Running "qunit:all" (qunit) task
Warning: Line 99: Unexpected identifier Use --force to continue.
Aborted due to warnings.
This does not help much since I have 100 of js files. I have looked into:
https://github.com/gruntjs/grunt-contrib-qunit
and tried to add the following to my Gruntfile.js (grunt.event.on):
module.exports = function(grunt) {
"use:strict";
var reportDir = "output/reports/"+(new Date()).getTime().toString();
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
qunit: {
options: {
'--web-security': 'no',
coverage: {
src: ['../src/**/*.js'],
instrumentedFiles: 'output/instrument/',
htmlReport: 'output/coverage',
coberturaReport: 'output/',
linesTresholdPct: 85
}
},
all: ["testsSuites.html"]
}
});
// Has no effect
grunt.event.on('qunit.error.onError', function (msg, stack) {
grunt.util._.each(stack, function (entry) {
grunt.log.writeln(entry.file + ':' + entry.line);
});
grunt.warn(msg);
});
grunt.loadNpmTasks('grunt-contrib-qunit');
grunt.loadNpmTasks('grunt-qunit-istanbul');
grunt.registerTask('test', ['qunit']);
Where testsSuites.html contains:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="qunit/qunit.css">
<script src="qunit/qunit.js"></script>
<script src="sinonjs/sinon-1.7.3.js"></script>
<script src="sinonjs/sinon-qunit-1.0.0.js"></script>
<!-- Sources -->
<script src="../src/sample.js"></script>
<!-- Test-->
<script src="test/sample-test.js"></script>
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script>
</script>
</body>
</html>
But the source file where the problem is located is still not printed. Is is out of Grunts hands to verify source code/show line number/file where e.g a syntax error is located?
I have also tried running:
grunt test --debug 9
It prints some debug info but not any information regarding syntax errors in the javascript sources.
I have tried to install JSHint and call it on all my javascript source files:
for i in $(find ../src -iname "*.js"); do jshint $i; done
Now I get tons of errors but Grunt is still happy. If I introduce a simple syntax error e.g:
(function(){
var sampleVar 32;
}
to provoke an error in Grunt:
Running "qunit:all" (qunit) task
Warning: Line 2: Unexpected number Use --force to continue.
Aborted due to warnings.
it simply disappears in the stream of errors generated by JSHint. How do I filter JSHint "warnings" from critical errors that will actually make Grunt fail?
Or is it qunit that should be configured for more verbose output?
grunt-contrib-qunit will display filenames when encountering a syntax error. Take this simplified version of your Gruntfile.js:
module.exports = function(grunt) {
"use:strict";
grunt.initConfig({
qunit: {
options: { '--web-security': 'no' },
all: ["testsSuites.html"]
}
});
grunt.loadNpmTasks('grunt-contrib-qunit');
};
Running it gives the error you're looking for:
$ grunt qunit
Running "qunit:all" (qunit) task
Testing testsSuites.html F.
>> global failure
>> Message: SyntaxError: Parse error
>> file:///tmp/src/sample.js:2
Warning: 1/2 assertions failed (17ms) Use --force to continue.
Aborted due to warnings.
The issue you're having looks to be a bug(?) in grunt-qunit-istanbul. The warning you're getting:
Warning: Line 99: Unexpected identifier Use --force to continue.
is Grunt handling an uncaught exception. The exception is being raised by the grunt-qunit-istanbul task. You can prove it by modifying this line in your original Gruntfile.js from:
src: ['../src/**/*.js'],
to:
src: ['../src/**/*.js.nomatch'],
This will prevent grunt-qunit-istanbul from finding and parsing any Javascript files before Qunit is run. If you let Qunit run, its error handler prints out the filenames with syntax errors like you want.
The only fix is the workaround I've described, or to patch grunt-qunit-istanbul to add an error handler for parse errors like Qunit does.
Patching grunt-qunit-istanbul
The function that is throwing the exception is Instrumenter.instrumentSync, which it is supposed to do:
instrumentSync ( code, filename )
Defined in lib/instrumenter.js:380
synchronous instrumentation method. Throws when illegal code is passed to it
You can fix it by wrapping the function call:
diff -r 14008db115ff node_modules/grunt-qunit-istanbul/tasks/qunit.js
--- a/node_modules/grunt-qunit-istanbul/tasks/qunit.js Tue Feb 25 12:14:48 2014 -0500
+++ b/node_modules/grunt-qunit-istanbul/tasks/qunit.js Tue Feb 25 12:19:58 2014 -0500
## -209,7 +209,11 ##
// instrument the files that should be processed by istanbul
if (options.coverage && options.coverage.instrumentedFiles) {
- instrumentedFiles[fileStorage] = instrumenter.instrumentSync(String(fs.readFileSync(filepath)), filepath);
+ try {
+ instrumentedFiles[fileStorage] = instrumenter.instrumentSync(String(fs.readFileSync(filepath)), filepath);
+ } catch (e) {
+ grunt.log.error(filepath + ': ' + e);
+ }
}
cb();
Then the test will keep running (and inform you of the syntax error):
$ grunt qunit
Running "qunit:all" (qunit) task
>> /tmp/src/sample.js: Error: Line 2: Unexpected number
Testing testsSuites.html F.
>> global failure
>> Message: SyntaxError: Parse error
>> file:///tmp/src/sample.js:2
Warning: 1/2 assertions failed (19ms) Use --force to continue.
Aborted due to warnings.
I have used grunt-contrib-qunit in the past but I have never attempted something like this. The problem you are facing is fairly interesting because the docs mention that the event qunit.error.onError should be emitted by grunt but it is not happening for you.
I created a new project using a jquery template and changed the code so that my test would fail. After that I wrote the following code:
grunt.event.on('qunit.error.onError', function(message, stackTrace) {
grunt.file.write('log/qunit-error.log', message);
});
When I ran the command grunt, I received no output in the file. To check this, I made a change to the event:
grunt.event.on('qunit.log', function(result, actual, expected, message, source) {
grunt.file.write('log/qunit-error.log', message);
});
Now, this piece of code did give me the error message in my file but it was useless because I could not get the stacktrace or the exact error message.
After this, I though of reading up the source and this is what I found:
phantomjs.on('error.onError', function (msg, stackTrace) {
grunt.event.emit('qunit.error.onError', msg, stackTrace);
});
The grunt event is only emitted when phantomjs throws an error.
At the moment I am not sure how I can get a phantomjs error while testing a simple JavaScript file without any browser related testing. This is my analysis so far and I hope this helps you in someway.

Programmatically install with bower?

I'm writing a grunt task and I want to install a dependency programmatically. However, I can't seem to figure out how to use their API.
This works just fine, but parsing the response is brittle because it uses the CLI:
grunt.util.spawn({
cmd: 'bower',
args: ['install', '--save', 'git#github.com:foo/bar.git']
}, function(none, message) {
grunt.log.writeln(message);
});
This does not work:
bower.commands.install.line(['--save', 'git#github.com:foo/bar.git'])
.on('end', function(data) {
grunt.log.writeln(data);
done();
})
.on('err', function(err) {
grunt.log.fail(err);
done();
});
I get the following error:
$ grunt my-task
Running "my-task:default_options" (my-task) task
Fatal error: Could not find any dependencies
What is the right way to do this?
The line() function expects the whole argv, so should be:
bower.commands.install.line(['node', 'bower', '--save', 'git#github.com:foo/bar.git']);
However, you should rather just pass paths and options to the install() method directly:
bower.commands.install(['git#github.com:foo/bar.git'], {save: true});

configuring requirejs reading from node_modules

I'm trying to setup a nodejs project to use requirejs. I call my program with node r.js ./config/main.js and my main.js looks like the following:
var cs = require("coffee-script");
var requirejs = require("requirejs");
requirejs.config({
nodeRequire: require,
baseUrl: ".",
paths: {
cs: "cs",
CoffeeScript: "CoffeeScript",
csBuild: "csBuild",
express: "express",
nohm: "nohm",
redback: "redback",
_: "underscore",
"connect-redis": "connect-redis",
freebase: "freebase"
}
});
console.log("hetet");
requirejs(["cs!./config/app"], function(app){
console.log("closing")
});
and inside app.coffee:
define((require) ->
express = require("express")
RedisStore = require("connect-redis")(express)
app = express.createServer()
config = require('cs!./config')
require('cs!./setup')(app, express, RedisStore)
require('cs!./routes')(app)
require('cs!../src/server')
app.listen(config.server.port)
)
I seem to fail in main.js with the error:
node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: Calling node's require("config") failed with error: Error: Calling node's require("config") failed with error: Error: Cannot find module 'config'
and What I have noticed is when I comment out the line var requirejs = require("requirejs"); (in main.js), I get further and fail at the line RedisStore = require("connect-redis")(express) (in app.coffee) with the error:
node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
^
TypeError: undefined is not a function
at ./config/app.coffee:10:41
I have been having a lot of trouble configuring requirejs in node any help would be appreciated.
thanks
It is best to not configure requirejs to look in node_modules, since modules in that area are modules formatted for node. There is a little bit more info in the requirejs node page.

Categories

Resources