Skip to content

Instantly share code, notes, and snippets.

@Raynos
Last active August 29, 2015 13:59
Show Gist options
  • Select an option

  • Save Raynos/10564079 to your computer and use it in GitHub Desktop.

Select an option

Save Raynos/10564079 to your computer and use it in GitHub Desktop.

Using channels as errors

One form of bug in I/O programmer is forgetting to handle an error.

var stream = new Socket(host, port)

// stream.error.input.take().then(function (err) {
//   /* handle error here */
// })

This is an example of not handling a streaming error.

Other systems provide mechanisms to handle with this bug at runtime

Other systems

promises

var promise = readThing()

// promise.then(null, function (err) {
//   /* handle error here */
// })

Promise implementations allow you to configure a global handler to detect these types of bugs

Promise.onPossiblyUnhandledRejection(function (err) {
  // oops. programmer error. report something
})

C++ objects

var handle = createRawSocket(...)

// handle.onerror = function (err) {
//   /* handle error here */
// }

JavaScript by default will throw if you try to invoke a non existant method. This means you can use the global error handler to listen for these errors

node event emitters

var stream = createReadStream(...)

// stream.on('error', function (err) {
//   /* handle error here */
// })

Node's implementation of event emitters has a special clause where if there are no 'error' listeners it will throw any error objects that are emitted.

This means you can use the global error handler to listen for these errors.

Possible fixes

There are two styles of fixes, either you can provide a global 'onPossiblyUntakenError' hook or you can throw any untaken errors.

function ErrorChannel(buffer) {
  Channel.call(this, buffer);

  var handling = false;

  var _take = this.input.take;
  this.input.take = function () {
    handling = true;

    return _take.call(this).then(function (v) {
      handling = false;
      return v;
    });
  };

  var _put = this.output.put;
  this.output.put = function (err) {
    if (handling) {
      return _put.call(this, err);
    }

    /* either throw or pass to onPossiblyUntakenError */
    throw err;
  };
}

util.inherits(ErrorChannel, Channel);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment