गपशप देखने / दुर्घटनाग्रस्त होने से त्रुटियों को रोकें


178

मैं gulp 3.6.2 चला रहा हूं और निम्नलिखित कार्य है जो एक नमूना ऑनलाइन से सेट किया गया था

gulp.task('watch', ['default'], function () {
  gulp.watch([
    'views/**/*.html',        
    'public/**/*.js',
    'public/**/*.css'        
  ], function (event) {
    return gulp.src(event.path)
      .pipe(refresh(lrserver));
  });

  gulp.watch(['./app/**/*.coffee'],['scripts']);
  gulp.watch('./app/**/*.scss',['scss']);
});

किसी भी समय मेरे CoffeeScript gulp घड़ी के स्टॉप में कोई त्रुटि है - जाहिर है कि मैं क्या चाहता हूं।

जैसा कि कहीं और की सिफारिश की मैंने यह कोशिश की

gulp.watch(['./app/**/*.coffee'],['scripts']).on('error', swallowError);
gulp.watch('./app/**/*.scss',['scss']).on('error', swallowError);
function swallowError (error) { error.end(); }

लेकिन यह काम नहीं करता है।

मैं क्या गलत कर रहा हूं?


@ Aperçu के उत्तर के जवाब में मैंने अपनी swallowErrorविधि को संशोधित किया और इसके बजाय निम्नलिखित की कोशिश की:

gulp.task('scripts', function () {
  gulp.src('./app/script/*.coffee')
    .pipe(coffee({ bare: true }))
    .pipe(gulp.dest('./public/js'))
    .on('error', swallowError);
});

पुनरारंभ किया गया, और फिर मेरी कॉफी फ़ाइल में एक सिंटैक्स त्रुटि बनाई। वही मुद्दा:

[gulp] Finished 'scripts' after 306 μs

stream.js:94
      throw er; // Unhandled stream error in pipe.
            ^
Error: W:\bariokart\app\script\trishell.coffee:5:1: error: unexpected *
*
^
  at Stream.modifyFile (W:\bariokart\node_modules\gulp-coffee\index.js:37:33)
  at Stream.stream.write (W:\bariokart\node_modules\gulp-coffee\node_modules\event-stream\node_modules\through\index.js:26:11)
  at Stream.ondata (stream.js:51:26)
  at Stream.EventEmitter.emit (events.js:95:17)
  at queueData (W:\bariokart\node_modules\gulp\node_modules\vinyl-fs\node_modules\map-stream\index.js:43:21)
  at next (W:\bariokart\node_modules\gulp\node_modules\vinyl-fs\node_modules\map-stream\index.js:71:7)
  at W:\bariokart\node_modules\gulp\node_modules\vinyl-fs\node_modules\map-stream\index.js:85:7
  at W:\bariokart\node_modules\gulp\node_modules\vinyl-fs\lib\src\bufferFile.js:8:5
  at fs.js:266:14
  at W:\bariokart\node_modules\gulp\node_modules\vinyl-fs\node_modules\graceful-fs\graceful-fs.js:104:5
  at Object.oncomplete (fs.js:107:15)

3
आधिकारिक gulp रेसिपीज को github.com/gulpjs/gulp/tree/master/docs/recipes पर देखें जिसके लिए एक नुस्खा है ... संयोजन-स्ट्रीम-टू-हैंडल-स्ट्रीम-कॉम्बिनेटर 2 का उपयोग करके यह आधिकारिक उत्तर है!
danday74

जवाबों:


257

आपका swallowErrorकार्य इस तरह दिखना चाहिए:

function swallowError (error) {

  // If you want details of the error in the console
  console.log(error.toString())

  this.emit('end')
}

मुझे लगता है कि आपको इस फ़ंक्शन को उस कार्य की errorघटना पर बाँधना होगा जो गिर रहा था, watchकार्य नहीं , क्योंकि यह वह जगह नहीं है जहां समस्या आती है, आपको प्रत्येक कार्य पर यह त्रुटि कॉलबैक सेट करना चाहिए जो विफल हो सकता है, जैसे प्लगइन्स जो आपके पास होने पर टूट जाते हैं एक ;या कुछ और याद किया , watchकार्य को रोकने के लिए रोकने के लिए।

उदाहरण :

gulp.task('all', function () {
  gulp.src('./app/script/*.coffee')
    .pipe(coffee({ bare: true }))
    .on('error', swallowError)
    .pipe(gulp.dest('./public/js'))

  gulp.src('css/*.scss')
    .pipe(sass({ compass: true }))
    .on('error', swallowError)
    .pipe(cssmin())
    .pipe(gulp.dest('dist'))
})

वैकल्पिक रूप से, यदि आपको कोई अन्य मॉड्यूल शामिल करने में कोई आपत्ति नहीं है, तो आप अपने में एक अतिरिक्त फ़ंक्शन की घोषणा करने के लिए आपको gulp- उपयोग के लॉग फ़ंक्शन का उपयोग कर सकते हैं :gulpfile

.on('error', gutil.log)

लेकिन मैं भयानक गुलप-प्लम्बर प्लगइन पर एक नज़र डालने की सलाह दे सकता हूं , जिसका उपयोग घटना के onerrorहैंडलर को हटाने के लिए किया जाता है error, जिससे धाराएं टूट जाती हैं। यह उपयोग करने के लिए बहुत सरल है और यह आपको उन सभी कार्यों को पकड़ने से रोकता है जो विफल हो सकते हैं।

gulp.src('./app/script/*.coffee')
  .pipe(plumber())
  .pipe(coffee({ bare: true }))
  .pipe(gulp.dest('./public/js'))

संबंधित प्लगइन के निर्माता द्वारा इस लेख पर इसके बारे में अधिक जानकारी ।


तुम्हारी सहायता सराहनीय है। मेरा संपादन देखें। मुझे लगता है कि मैं वही कर रहा हूं जो आप कह रहे हैं और यह अभी भी काम नहीं कर रहा है
जॉर्ज मौयर

2
आप अपने उत्तर को अंतिम सही चीज़ को प्रतिबिंबित करने के लिए संपादित करना चाह सकते हैं ताकि भविष्य में ऐसा करने वाले किसी भी व्यक्ति को टिप्पणी श्रृंखला को पढ़ना न पड़े।
जॉर्ज मौयर

1
यह सब ठीक है और अच्छा है, लेकिन मुझे अपने स्वयं के त्रुटि हैंडलर क्यों लिखना होगा? पूरे कारण से मैं गल्प या ग्रंट या जो भी प्रीप्रोसेसिंग टूल का उपयोग करता हूं, वह यह है कि यह मेरे लिए गंदा काम करता है। मेरे कोड में कहीं भी एक सिंटैक्स त्रुटि (जो होने के लिए बाध्य है) पूरे सिस्टम को रोकना नहीं चाहिए। इसकी तुलना Prepros (एक अन्य प्रीप्रोसेसर) के GUI से करें - यह टूल आपको बताता है कि आपकी त्रुटि कहाँ है, और कुछ गलत होने पर लटका या छोड़ नहीं देता है।
कोकोडको

1
आश्चर्यजनक है कि किसी ने भी भाप-कॉम्बीनेर 2 का उल्लेख नहीं किया है, भले ही यह आधिकारिक गुलाल नुस्खा हो! प्लम्बर भी अच्छा है, लेकिन मैं हमेशा गल्प रेसिपी को फॉलो करना पसंद करता हूं, गल्प रेसिपी को
गॉलप

1
उसी पहेली का सामना करते हुए, मैंने चारों ओर एक आवरण का उपयोग करने का फैसला किया, जो घड़ी फ़ंक्शन के परिणाम में gulp.watch()जोड़ता .on('error', function() { this.emit('end') })है, क्योंकि यह विशेष रूप से घड़ी का काम है जिसे मैं लटकने के लिए लचीला बनाना चाहता हूं। वास्तव में अच्छी तरह से काम करता है, और व्यक्तिगत कार्य जो अभी भी विफल होते हैं वे अपने स्वयं के त्रुटि संदेश प्रिंट करते हैं। कोड देखें: github.com/specious/specious.github.io/commit/f8571d28
tknomad

20

उपरोक्त उदाहरण मेरे लिए काम नहीं किया। हालांकि निम्नलिखित ने किया:

var plumber = require('gulp-plumber');
var liveReload = require('gulp-livereload');
var gutil = require('gulp-util');
var plumber = require('gulp-plumber');
var compass = require('gulp-compass');
var rename = require('gulp-rename');
var minifycss = require('gulp-minify-css');
var notify = require('gulp-notify');

gulp.task('styles', function () {
    //only process main.scss which imports all other required styles - including vendor files.
    return gulp.src('./assets/scss/main.scss')
            .pipe(plumber(function (error) {
                gutil.log(error.message);
                this.emit('end');
            }))
            .pipe(compass({
                config_file: './config.rb',
                css: './css'
                , sass: './assets/scss'
            }))
            //minify files
            .pipe(rename({suffix: '.min'}))
            .pipe(minifycss())

            //output
            .pipe(gulp.dest('./css'))
            .pipe(notify({message: 'Styles task complete'}));
});

gulp.task('watch', function () {
    liveReload.listen();
    gulp.watch('assets/scss/**/*.scss', ['styles']);
});

यह महान है, लेकिन यदि कोई त्रुटि होती है (वर्तमान में यह सिर्फ में टर्मिनल त्रुटि लॉग) था भी सूचित करने के लिए अच्छा होगा
अस्तित्व के प्रति

4

फ़ाइलों के एक प्रारूप के साथ

(पूर्व: *। केवल कॉफ़ी)

यदि आप फ़ाइलों के केवल एक प्रारूप के साथ काम करना चाहते हैं, तो gulp-plumberआपका समाधान है।

उदाहरण के लिए अमीर संभाला त्रुटियों और coffeescripting के लिए चेतावनी:

gulp.task('scripts', function() {
  return gulp.src(['assets/scripts/**/*.coffee'])
    .pipe(plumber())
    .pipe(coffeelint())
    .pipe(coffeelint.reporter())
    .pipe(lintThreshold(10, 0, lintThresholdHandler))
    .pipe(coffee({
      bare: true
    }))
    .on('error', swallowError)
    .pipe(concat('application.js'))
    .pipe(gulp.dest('dist/scripts'))
    .pipe(rename({ suffix: '.min' }))
    .pipe(uglify())
    .pipe(gulp.dest('dist/scripts'))
    .pipe(notify({ message: 'Scripts task complete' }));
});

कई प्रकार के फ़ाइल स्वरूपों के साथ

(उदा: *। कॉफ़ी और * .js एक ही समय में)

लेकिन अगर आप कई प्रकार के फ़ाइल स्वरूपों (उदाहरण के लिए: *.jsऔर *.coffee) के साथ काम नहीं करेंगे , तो मैं अपने समाधान पोस्ट करूँगा।

मैं बस यहाँ पर एक आत्म व्याख्यात्मक कोड पोस्ट करूँगा, पहले कुछ विवरण के साथ।

gulp.task('scripts', function() {
  // plumber don't fetch errors inside gulpif(.., coffee(...)) while in watch process
  return gulp.src(['assets/scripts/**/*.js', 'assets/scripts/**/*.coffee'])
    .pipe(plumber())
    .pipe(gulpif(/[.]coffee$/, coffeelint()))
    .pipe(coffeelint.reporter())
    .pipe(lintThreshold(10, 0, lintThresholdHandler))
    .pipe(gulpif(/[.]coffee$/, coffee({ // if some error occurs on this step, plumber won't catch it
      bare: true
    })))
    .on('error', swallowError)
    .pipe(concat('application.js'))
    .pipe(gulp.dest('dist/scripts'))
    .pipe(rename({ suffix: '.min' }))
    .pipe(uglify())
    .pipe(gulp.dest('dist/scripts'))
    .pipe(notify({ message: 'Scripts task complete' }));
});

मैंने इस मुद्दे का सामना किया gulp-plumberऔर gulp-ifउपयोग कियाgulp.watch(...

संबंधित समस्या यहाँ देखें: https://github.com/floatdrop/gulp-plumber/issues/23

तो मेरे लिए सबसे अच्छा विकल्प था:

  • फ़ाइल के रूप में प्रत्येक भाग, और उसके बाद संक्षिप्त । कई कार्य बनाएं जो प्रत्येक भाग को अलग फ़ाइल (जैसे ग्रंट करता है) में संसाधित कर सकते हैं, और उन्हें संक्षिप्त कर सकते हैं
  • धारा के रूप में प्रत्येक भाग, और धाराओं के बाद विलय । एक में दो धाराओं merge-stream(जो कि से बनाया गया था event-stream) को मिलाएं और काम जारी रखें (मैंने कोशिश की कि पहले, और यह मेरे लिए ठीक है, इसलिए यह पिछले एक की तुलना में तेज़ समाधान है)

धारा के रूप में प्रत्येक भाग, और धाराओं के बाद विलय

उसका मेरे कोड का मुख्य भाग है:

gulp.task('scripts', function() {
  coffeed = gulp.src(['assets/scripts/**/*.coffee'])
    .pipe(plumber())
    .pipe(coffeelint())
    .pipe(coffeelint.reporter())
    .pipe(lintThreshold(10, 0, lintThresholdHandler))
    .pipe(coffee({
      bare: true
    }))
    .on('error', swallowError);

  jsfiles = gulp.src(['assets/scripts/**/*.js']);

  return merge([jsfiles, coffeed])
    .pipe(concat('application.js'))
    .pipe(gulp.dest('dist/scripts'))
    .pipe(rename({ suffix: '.min' }))
    .pipe(uglify())
    .pipe(gulp.dest('dist/scripts'))
    .pipe(notify({ message: 'Scripts task complete' }));
});

फ़ाइल के रूप में प्रत्येक भाग, और उसके बाद संक्षिप्त

यदि इसे भागों में अलग करना है, तो प्रत्येक भाग में एक परिणाम फ़ाइल बनाई जानी चाहिए। पूर्व के लिए:

gulp.task('scripts-coffee', function() {

  return gulp.src(['assets/scripts/**/*.coffee'])
    .pipe(plumber())
    .pipe(coffeelint())
    .pipe(coffeelint.reporter())
    .pipe(lintThreshold(10, 0, lintThresholdHandler))
    .pipe(coffee({
      bare: true
    }))
    .on('error', swallowError)
    .pipe(concat('application-coffee.js'))
    .pipe(gulp.dest('dist/scripts'));

});

gulp.task('scripts-js', function() {

  return gulp.src(['assets/scripts/**/*.js'])
    .pipe(concat('application-coffee.js'))
    .pipe(gulp.dest('dist/scripts'));

});

gulp.task('scripts', ['scripts-js', 'scripts-coffee'], function() {

  var re = gulp.src([
    'dist/scripts/application-js.js', 'dist/scripts/application-coffee.js'
  ])
    .pipe(concat('application.js'))
    .pipe(gulp.dest('dist/scripts'))
    .pipe(rename({ suffix: '.min' }))
    .pipe(uglify())
    .pipe(gulp.dest('dist/scripts'))
    .pipe(notify({ message: 'Scripts task complete' }));

  del(['dist/scripts/application-js.js', 'dist/scripts/application-coffee.js']);

  return re;

});

पुनश्च:

यहां उपयोग किए गए नोड मॉड्यूल और फ़ंक्शन:

// Load plugins
var gulp = require('gulp'),
    uglify = require('gulp-uglify'),
    rename = require('gulp-rename'),
    concat = require('gulp-concat'),
    notify = require('gulp-notify'),
    plumber = require('gulp-plumber'),
    merge = require('ordered-merge-stream'),
    replace = require('gulp-replace'),
    del = require('del'),
    gulpif = require('gulp-if'),
    gulputil = require('gulp-util'),
    coffee = require('gulp-coffee'),
    coffeelint = require('gulp-coffeelint),
    lintThreshold = require('gulp-coffeelint-threshold');

var lintThresholdHandler = function(numberOfWarnings, numberOfErrors) {
  var msg;
  gulputil.beep();
  msg = 'CoffeeLint failure; see above. Warning count: ';
  msg += numberOfWarnings;
  msg += '. Error count: ' + numberOfErrors + '.';
  gulputil.log(msg);
};
var swallowError = function(err) {
  gulputil.log(err.toString());
  this.emit('end');
};

मुझे अभी भी इस टिप्पणी के लिए सुधार दिखाई दे रहे हैं। गति तुलना की तरह, और केवल .js फ़ाइलों के लिए लिंक (minified या 3D पार्टी लाइब्रेरीज़ को छोड़कर, या bower_computer से लिबास के लिए)। लेकिन मूल रूप से Google.com
रोमन एम। कोस

3

मुझे गल्प प्लंबर का उपयोग करना पसंद है क्योंकि यह एक कार्य के लिए एक वैश्विक श्रोता को जोड़ सकता है और एक सार्थक संदेश प्रदर्शित कर सकता है।

var plumber = require('gulp-plumber');

gulp.task('compile-scss', function () {
    gulp.src('scss/main.scss')
        .pipe(plumber())
        .pipe(sass())
        .pipe(autoprefixer())
        .pipe(cssnano())
        .pipe(gulp.dest('css/'));
});

संदर्भ: https://scotch.io/tutorials/prevent-errors-from-crashing-gulp-watch


2

मैंने https://github.com/gulpjs/gulp/issues/71 के लिए निम्नलिखित हैक के रूप में लागू किया है :

// Workaround for https://github.com/gulpjs/gulp/issues/71
var origSrc = gulp.src;
gulp.src = function () {
    return fixPipe(origSrc.apply(this, arguments));
};
function fixPipe(stream) {
    var origPipe = stream.pipe;
    stream.pipe = function (dest) {
        arguments[0] = dest.on('error', function (error) {
            var state = dest._readableState,
                pipesCount = state.pipesCount,
                pipes = state.pipes;
            if (pipesCount === 1) {
                pipes.emit('error', error);
            } else if (pipesCount > 1) {
                pipes.forEach(function (pipe) {
                    pipe.emit('error', error);
                });
            } else if (dest.listeners('error').length === 1) {
                throw error;
            }
        });
        return fixPipe(origPipe.apply(this, arguments));
    };
    return stream;
}

इसे अपने gulpfile.js में जोड़ें और इसे इस तरह उपयोग करें:

gulp.src(src)
    // ...
    .pipe(uglify({compress: {}}))
    .pipe(gulp.dest('./dist'))
    .on('error', function (error) {
        console.error('' + error);
    });

यह मेरे लिए सबसे प्राकृतिक त्रुटि से निपटने जैसा लगता है। यदि कोई त्रुटि हैंडलर नहीं है, तो यह एक त्रुटि फेंक देगा। नोड v0.11.13 के साथ परीक्षण किया गया।


2

इसका एक सरल उपाय यह है कि gulp watchएक बैश (या श) शेल के भीतर एक अनंत लूप में रखा जाए ।

while true; do gulp; gulp watch; sleep 1; done

इस कमांड के आउटपुट को अपनी स्क्रीन पर दृश्य क्षेत्र में रखें क्योंकि आप अपना जावास्क्रिप्ट एडिट करते हैं। जब आपके संपादन में त्रुटि होती है, तो गुल दुर्घटनाग्रस्त हो जाएगा, इसके स्टैक ट्रेस को प्रिंट करें, एक सेकंड के लिए प्रतीक्षा करें, और अपनी स्रोत फ़ाइलों को देखना फिर से शुरू करें। तब आप सिंटैक्स त्रुटि को ठीक कर सकते हैं, और गुल इंगित करेगा कि क्या संपादन सामान्य आउटपुट था, या फिर क्रैश (फिर से शुरू) फिर से प्रिंट करके एक सफलता थी या नहीं।

यह एक लिनक्स या मैक टर्मिनल में काम करेगा। यदि आप विंडोज का उपयोग कर रहे हैं, तो Cygwin या Ubuntu Bash (विंडोज 10) का उपयोग करें।


यह कौनसी भाषा है? इसके अलावा, क्या सुझाए गए समाधानों से इसका कोई लाभ है?
जॉर्ज मौएर

यह बाश / श में लिखा गया है। इसे अन्य समाधानों की तुलना में कम कोड की आवश्यकता होती है और इसे याद रखना और कार्यान्वित करना आसान होता है।
जेसी होगन

क्या आप इस तथ्य को संपादित कर सकते हैं कि इसका जवाब और इस पर आपके अन्य विचार आपके उत्तर में हैं? मैं इस बात से सहमत नहीं हूं कि इसका आसान प्लम्बर, लेकिन इसका वैध (यदि क्रॉस प्लेटफॉर्म नहीं है) दृष्टिकोण। मैंने शुरू में मतदान किया क्योंकि यह स्पष्ट नहीं था कि यह किस भाषा में है और जब तक आप जवाब संपादित नहीं करते मैं अपना वोट नहीं बदल सकता।
जॉर्ज मौअर

1
तो आप स्ट्रीम को क्रैश करना पसंद करते हैं और पूरी प्रक्रिया को फिर से शुरू करना चाहते हैं जो इस बात पर निर्भर करता है कि आप एक अनंत लूप के साथ क्या कर रहे हैं, केवल इस त्रुटि को पकड़ने के बजाय? मुझे थोड़ा परेशान करता है। और कम कोड की बात करें, तो आपको अपने कार्य में प्लम्बर जोड़ने के लिए 16 वर्णों की आवश्यकता होती है, जबकि आपका समाधान गिनती किए बिना 36 लेता है gulp watch
Balthazar

प्रतिक्रिया के लिए धन्यवाद, @GeorgeMauer, मैंने संपादन किया और इसमें काम करने वाले वातावरण / प्लेटफार्मों के बारे में लिखा।
जेसी होगन

1

टाइपप्रति

इसी से मेरा काम बना है। मैं Typescriptहैंडल करने के लिए फ़ंक्शन ( thisकीवर्ड के साथ एनोविड भ्रम ) के साथ काम करता हूं और अलग हो जाता हूं less। इसके साथ Javascriptही काम करता है ।

var gulp = require('gulp');
var less = require('gulp-less');

gulp.task('less', function() {
    // writing a function to avoid confusion of 'this'
    var l = less({});
    l.on('error', function(err) {
        // *****
        // Handle the error as you like
        // *****
        l.emit('end');
    });

    return gulp
        .src('path/to/.less')
        .pipe(l)
        .pipe(gulp.dest('path/to/css/output/dir'))
})

अब, जब आप watch .lessफाइल करते हैं, और एक errorहोता है, तो watchबंद नहीं होगा और नए परिवर्तन आपके अनुसार संसाधित होंगे less task

नोट : मैंने कोशिश की l.end();; हालांकि, यह काम नहीं किया। तथापि,l.emit('end'); पूरी तरह से काम करता है।

उममीद है कि इससे मदद मिलेगी। शुभ लाभ।


1

इसने मेरे लिए काम किया ->

var gulp = require('gulp');
var sass = require('gulp-sass');

gulp.task('sass', function(){
    setTimeout(function(){
        return gulp.src('sass/*.sass')
        .pipe(sass({indentedSyntax: true}))
        .on('error', console.error.bind(console))
        .pipe(gulp.dest('sass'));
    }, 300);
});



gulp.task('watch', function(){
    gulp.watch('sass/*.sass', ['sass']);
});

gulp.task('default', ['sass', 'watch'])

मैंने सिर्फ .on ('त्रुटि', कंसोल .error.bind (कंसोल) लाइन को जोड़ा है, लेकिन मुझे gulp कमांड को रूट के रूप में चलाना था। मैं एक php एप्लिकेशन पर नोड gulp चला रहा हूं, इसलिए मेरे पास एक सर्वर पर कई खाते हैं, यही वजह है कि मैं सिंटैक्स त्रुटियों पर gulp को तोड़ने के मुद्दे पर भाग गया क्योंकि मैं gulp को रूट के रूप में नहीं चला रहा था ... शायद प्लम्बर और कुछ अगर मैं जड़ के रूप में भागता तो मेरे लिए यहां अन्य उत्तर काम करते। उत्तर के लिए Accio कोड https://www.youtube.com/watch?v=iMR7hq4ABOw को क्रेडिट । उन्होंने कहा कि त्रुटि को संभालने से आपको यह निर्धारित करने में मदद मिलती है कि त्रुटि किस रेखा पर है और यह कंसोल में क्या है, लेकिन सिंटैक्स त्रुटि पर भी टूटना बंद कर देता है। उन्होंने कहा कि यह एक हल्के वजन को ठीक करने जैसा था, इसलिए यह निश्चित नहीं है कि यह आपके लिए क्या काम करेगा। एक शॉट के लायक, हालांकि जल्दी ठीक। आशा है कि यह किसी की मदद करता है!

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.