24Nov

expess_1_2

Hey, guys! Let’s continue our lesson about Express basics and Middleware.

The result is (add to app.js):

app.use(function(req, res, next) {
  if (req.url == '/') {
    res.end("Hello");
  } else {
    next();
  }
});

The function next serves to deliver control further down the chain to the next Middlewareor to the next function that is announced through app.use. The second Middleware can also check something and transfer control further:

// Middleware
app.use(function(req, res, next) {
  if (req.url == '/') {
    res.end("Hello");
  } else {
    next();
  }
});

app.use(function(req, res, next) {
  if (req.url == '/test') {
    res.end("Test");
  } else {
    next();
  }
});

Launch it in a following way and see what we’ve got.

http://localhost:3000/

http://localhost:3000/test

Everything works.

And what will happen, if we follow a page that does not exist?

http://localhost:3000/nopage

The integrated Express handler has worked. If there is no  Middleware , next has been called, and the next Middleware does not exist, Express outputs a ‘Not Found’ page by default. In order to influence it somehow, let us create one more Middleware to receive req and resthe one that will always be the last in this chain:

app.use(function(req, res) {
  res.send(404, "Page Not Found Sorry");
});

Launch it. Note, there is a correct 404 status in console. Here we’ve just used the method res.send. Standard req and res elements lack it, but you can find it in  Express, for the reason it expands req  and res  objects prior to calling a Middleware chain, expands objects through inheriting and adds some of its methods to them. These methods can be found at expressjs.com. There you will find API Reference that includes a lot of things – in particular, we need Response and a send method. Its simple form is: res.send(hello world); – to send a line, but there are some more challenging and interesting variants:

res.send(new Buffer('whoop'));
res.send({ some: 'json' });
res.send('<p>some html</p>');
res.send(404, 'Sorry, we cannot find that!');
res.send(500, { error: 'something blew up' });
res.send(200);

Send can send various things: Bufferjson, text; and if the first argument is a number, it puts a respective status, too. So, this method is quite versatile and handy.

But what will happen, if we’ve got an error somewhere? Let us create a special Middlewarecall it error, and there will actually be an error:

app.use(function(req, res, next) {
  if (req.url == '/error') {
    BLABLA()
  } else {
    next();
  }
});

Go to :

http://localhost:3000/error

The built-in Express error handler has worked. It works only when  Middleware has throw.

app.use(function(req, res, next) {
  if (req.url == '/error') {
    throw new Error ('......')
  } else {
    next();
  }
});

Of course, it won’t work, if this throw is wrapped into setTimeout. That’s what the principle of JavaScript is.

Now let us deal with the correct handling of all errors – the ones that occur in the average process of work of our website. Let us pretend, a user has followed a url that is forbidden for entering. In this case we can either notify him immediately (res.send(401)), or sometimes it is even more convenient to deliver the error further down the chain. That’s how it looks like (let us change our previous function):

app.use(function(req, res, next) {
  if (req.url == '/forbidden') {
    next(new Error("wops, denied"));
  } else {
    next();
  }
});

If there is some argument inside next Express knows it is an error and delivers it to an error handler. By default, a handler of this kind, as we’ve already seen, outputs a stack, which is inappropriate in real situations. So, we can create our own handler. It is programmed in the same way as Middlewarewhile app.use is just a function with 4 instead of 3 elements:

app.use(function(err, req, res, next) {

In JavaScript every function has a length property that contains a number of arguments in its declaration, that’s why when seeing a function with 4 arguments, Express is able to understand it is an error handler. Respectively, if an error occurs – either  throw or  next has been called with an argument – the control gets immediately transferred to

app.use(function(err, req, res, next) {

}

Here we can already output an error: in a development case it will be stack, and in real life it will be an error code, template, etc.

How can we know whether the script includes a development case or a real launch? For that reason, we’ve got a special value that can be received using app.get('env'). If a special  NODE_ENV environment variable is not specified, this thing will be development. But if it does include that variable, it will be equal to the value of this variable:

app.use(function(err, req, res, next) {  
  // NODE_ENV = 'production'  
  if (app.get('env') == 'development') { 

In real-life launch it has a value production.  Respectively, if it is developmentlet us output the error beautifully. For that reason, we’ve got a special built-in Middleware – express.errorHandler. Let us take it out of a generated template and insert here:

app.use(function(err, req, res, next) {  
  // NODE_ENV = 'production'  
  if (app.get('env') == 'development') {  
    app.use (express.errorHandler());  
}
}); 

What kind of thing is that? Let us take a precise look at our Express sources. What Express exports does not include errorHandler. To find it, we should look deeper in what’s going on here, in particular, in our loop:

for (var key in connect.middleware) {
  Object.defineProperty(
      exports
    , key
    , Object.getOwnPropertyDescriptor(connect.middleware, key));
}

Еxpress is a framework created around another framework called  connect. (starting from the version Express 4 it is not so anymore, but our lesson is built on the version Express 3). It contains various Middleware that get included into Express this way by default. Middleware can be found in

node modules→connect→ lib→middleware →errorHandler.

Now let us create errorHandler and deliver a request in an explicit view to it, as the previous code, unfortunately, won’t work:

app.use(function(err, req, res, next) {
  // NODE_ENV = 'production'
  if (app.get('env') == 'development') {
    var errorHandler = express.errorHandler();
    errorHandler(err, req, res, next);
  } else {
    res.send(500);
  }
});

Check it. We’ve got development, so the respective branch if has worked.

In our upcoming articles we will continue working with  Express, analyze built-in  Middlewares and output a normal html page.

The lesson code can be found here.

keep-calm-and-express-yourself-445

The materials for this article have been borrowed from the following screencast.

We are looking forward to meeting you on our website soshace.com

Interoperability between Ethereum, Binance Smart Chain, and other blockchain platforms using Node.js

In this article, I will deeply into the importance of interoperability in the blockchain sphere and present use cases that support this perspective. Additionally, I will provide code examples using Node.js to demonstrate the practical implementation of interoperability between Ethereum, Binance Smart Chain, and other blockchain platforms.

Leave a Reply