One place for hosting & domains

      Prevent

      Prevent Errors from Crashing Gulp Watch

      Introduction

      Developers are a lazy bunch. Or at least I assume we are. Because of this reason we tend to build tools that make our work faster. From highly customizable editors to task runners.

      With gulp, we can build tasks that automatically compile Sass, start a Laravel server, live reload the browser, transpile ES6 to ES5, etc.

      Thankfully, there are a few languages out there like Javascript which is very forgiving. Nonetheless, mistakes can happen.

      Since we have a “gulp watcher” that watches our project and runs defined tasks when we make any change, an error can easily break our pipeline.

      Watching in Gulp refers to triggering a task when a change is made to a project’s source.

      So, before we watch a task, let’s create a task that we will use as our example throughout this tutorial. The task we will create is a SCSS compilation task.

      We can create a new working directory, name it whatever you want. We can now create our gulpfile.js in our working directory. Then we add our build task. Before we define our task, we need to install our dependencies.

      For this article, here is a list of our dependencies.

      {
        "private": true,
        "devDependencies": {
          "gulp": "^3.9.1",
          "gulp-notify": "^2.2.0",
          "gulp-plumber": "^1.1.0",
          "gulp-sass": "^2.3.2",
          "gulp-util": "^3.0.7"
        }
      }
      

      Now that we have our dependency list, we can run npm install or if you have the new yarn package manager based on npm, you can run yarn install.

      In the gulpfile, we can then define our gulp task.

      const gulp = require('gulp');
      const sass = require('gulp-sass');
      
      gulp.task('compile-scss', function () {
          gulp.src('scss/main.scss')
              .pipe(sass())
              .pipe(gulp.dest('css/'));
      });
      

      So from the command line, we can run gulp compile-scss and our Sass file should be compiled.

      Watching a Task

      Now that we have a task defined, let’s trigger the file whenever we make a change to the project’s source.

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

      From the terminal, we can run gulp watch and whenever a file ending with .scss extension in any folder within the scss directory gets changed, compile-scss task is run.

      We’ve got our task and watcher up and running, but if an error occurs in our SCSS file, the gulp watcher gets terminated. We then have to go back to the terminal and type gulp watch again. This gets very annoying really fast. A silly little ; can break our watcher.

      To avoid breakage like this, we can one of three things:

      1. Swallow the Error.
      2. Gulp Util.
      3. Gulp Plumber.

      One a way to go about dealing with errors is to “swallow the error”. The error(s) will be taken in by the application to prevent the task from breaking. Basically, errors will not be reported and the task will keep running.

      Since gulp sends a lot of events, we can hook into the error event of the task we don’t want to fail.

      gulp.task('compile-scss', function () {
          gulp.src('scss/main.scss')
              .pipe(sass())
              .on('error', function (err) {
                  console.log(err.toString());
      
                  this.emit('end');
              })
              .pipe(gulp.dest('css/'));
      });
      

      As you can see above, from the on listener on the task. The on event listener takes in two parameters: the event and a function to be triggered when the event gets called. The function that gets called takes in the error object. We then log the stringified version of the error to the terminal.

      It is absolutely important to this.emit('end'), if this event is not triggered, the next pipe in this task pipeline never gets called, and the buffer will be left open.

      This method involves using the gulp-util plugin.

      The gulp-util plugin provides a lot of helpful methods, one of them is log. With this method, we can log the error to the terminal. To use this, we attach an error event listener to the pipe.

      var gutil = require('gulp-util');
      
      gulp.task('compile-scss', function () {
          gulp.src('scss/main.scss')
              .pipe(sass())
              .on('error', gutil.log)
              .pipe(gulp.dest('css/'));
      });
      

      But this method also requires us to go through each pipe in the pipeline and attach .on('error', gutil.log) listener to all tasks. Something like this.

      gulp.task('compile-scss', function () {
          gulp.src('scss/main.scss')
              .pipe(sass())
              .on('error', gutil.log)
              .pipe(autoprefixer())
              .on('error', gutil.log)
              .pipe(gulp.dest('css/'));
      });
      

      Out of all three methods, this is my favorite. With gulp-plumber, we don’t need to go to each pipe and add a listener, we can just add a global listener to the task and have a meaningful error displayed.

      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/'));
      });
      

      We can have multiple pipes in this task and still only ever need to call plumber once.

      Now that we can see the errors without breaking out of watch, we need to find a way to get some kind of notification when an error occurs. There are several ways to do this, but I will cover only one method.

      The method I will cover in this article: will play a beeping sound when an error occurs, and also show a system notification that looks like this.

      This notification looks different according to your operating system.

      To get this feature to work, we need to extend the gulp-plumber plugin. So in our gulp task, we update our call to plumber.

      gulp.task('scss', function () {
          gulp.src('scss/main.scss')
              .pipe(plumber({ errorHandler: function() {
                  
              }}))
              .pipe(sass())
              .pipe(gulp.dest('css'));
      });
      

      Notice, we pass an object that has an errorHandler property that takes a closure to plumber. We can then call our notify plugin in that closure.

      var notify = require('gulp-notify');
      
      gulp.task('scss', function () {
          gulp.src('scss/main.scss')
              .pipe(plumber({ errorHandler: function(err) {
                  notify.onError({
                      title: "Gulp error in " + err.plugin,
                      message:  err.toString()
                  })(err);
              }}))
              .pipe(sass())
              .pipe(gulp.dest('css'));
      });
      

      We call the notify plugin and pass it an object that has a title and message property. Now, when an error occurs, a notification is triggered. To play a beeping sound, we can use **gulp-util ** for that.

      var notify = require('gulp-notify');
      
      gulp.task('scss', function () {
          gulp.src('scss/main.scss')
              .pipe(plumber({ errorHandler: function(err) {
                  notify.onError({
                      title: "Gulp error in " + err.plugin,
                      message:  err.toString()
                  })(err);
      
                  
                  gutil.beep();
              }}))
              .pipe(sass())
              .pipe(gulp.dest('css'));
      });
      

      Now, when an error occurs, we get both sound and system notification, and then you can check your terminal for more information.

      The configuration in this article should be suitable for most users, but if you have any suggestions/improvements, please let us know in the comments.

      How to Prevent Route Leaks with Inbound and Outbound Route Mapping


      As citizens of the internet, it’s our responsibility to be a good neighbor by configuring and managing an autonomous system (AS) that follows proper Border Gateway Protocol (BGP). Improper configuration and management can hold dire consequences, including route leaks.

      During the summer, a high-profile route leak event prevented access to Amazon, Facebook, Cloudflare and others over a two hour period. Let’s explore route leaks in greater depth and learn how events like this can be prevented. If you’d like to brush up on BGP and how default BGP can impact your network performance before diving in, you can get a refresher here.

      What is a Route Leak?

      Simply put, a route leak occurs when internet traffic is routed through unintended paths. More specifically, route leaks happen when an AS advertises prefixes it’s not entitled to advertise.

      When an AS advertises prefixes it should not be announcing, some or all traffic destined for the prefix will get redirected to the unwarranted AS, never reaching the intended destination. This is often due to BGP misconfigurations but can also be the result of malicious intent.

      The high-profile route leak event over the summer was caused by a small company advertising more specific prefixes introduced by a route optimization appliance. This event could have been avoided if either the small company or its upstream ISPs had followed some basic best practices in their BGP configurations to eliminate the risk of a route leak.

      Avoiding Route Leaks with Route Mapping

      A small company advertising prefixes to upstream ISPs can use route maps to effectively prevent re-announcing incorrect prefixes. Route maps can be used both on the inbound and the outbound BGP sessions.

      In the event mentioned above, an inbound route map should have been used on the BGP session with the route optimizer and set the well-known BGP community for NO EXPORT on routes received. The NO EXPORT BGP community informs the receiving router’s BGP process that it should not advertise the prefixes heard on this session to External Border Gateway Protocol (eBGP) neighbors. This would have prevented any more specific prefixes from being leaked to the upstream ISPs.

      Inbound Route Maps

      ISPs can use inbound route maps with their customers to limit their expected prefixes. The inbound route map matches only a set of prefixes the customer can announce (as informed by route registries) and allows those routes in the ISP’s route tables.

      The ISP can also limit the number of prefixes that a customer can announce before shutting down the BGP session using the maximum-prefix feature. Using maximum-prefix does not necessarily keep an AS from advertising errant routes, but it can limit the scope of a potential route leak.

      Outbound Route Maps

      Outbound route maps can also be configured by an advertising AS to limit the prefixes that are sent out via BGP. Like the inbound route map on the ISP side of the BGP session, the downstream AS can use an outbound route map to match a prefix list with prefixes a company is permitted to advertise. This prevents any additional prefixes from getting into the ISP’s route tables and out to the larger internet.

      Closing Thoughts

      Route leaks, and to some degree route hijacking, which is defined by malicious intent, are avoidable as long as AS entities and their upstream providers take the time to configure BGP properly to avoid them. Inbound and outbound route mapping are just a couple of best practices that can eliminate potential route leaks before they become major problems.

      Explore INAP’s Global Network.

      LEARN MORE

      David Heidgerken


      David Heidgerken is a Solution Engineer, aligning technical specifications with customer expectations to create IT solutions that successfully deliver better technological outcomes. READ MORE



      Source link