Categories
JavaScript Nodejs

Node.js FS Module — Write Streams

Manipulating files and directories are basic operations for any program. Since Node.js is a server-side platform and can interact with the computer that it’s running on directly, being able to manipulate files is a basic feature.

Fortunately, Node.js has a fs module built into its library. It has many functions that can help with manipulating files and folders.

File and directory operation that are supported include basic ones like manipulating and opening files in directories.

Likewise, it can do the same for files. It can do this both synchronously and asynchronously. It has an asynchronous API that has functions that support promises.

Also, it can show statistics for a file. Almost all the file operations that we can think of can be done with the built-in fs module. In this article, we will create write streams to write a file’s data sequentially and listen to events from a write stream. Since Node.js WriteStreams are descendants of the Writable object, we will also listen to events to it.

Streams are collections of data that may not be available all at once and don’t have to fit in memory. This makes stream handy for processing large amounts of data.

It’s handy for files because files can be big and streams can let us get a small amount of data at one time. In the fs module, there are 2 kinds of streams. There’s the ReadStream and the WriteStream. We get the data into a WriteStream via a ReadStream.

WriteStream

A WriteStream is for used for writing data to a file. We can get the input into our WriteStream via the ReadStream’s pipe function. The data from the ReadStream is sent to the write stream in small chunks so that the host computer won’t run out of memory.

To define a WriteStream, we can use the fs.createWriteStream function. The function takes 2 arguments.

The first argument is the path of the file. The path can be in the form of a string, a Buffer object, or an URL object. The path can be in the form of a string, a Buffer object, or an URL object.

The second argument is an object that can have a variety of options as properties. The flag option is the file system flag for setting the mode for opening the file. The default flag is w. The list of flags are below:

  • 'a' – Opens a file for appending, which means adding data to the existing file. The file is created if it does not exist.
  • 'ax' – Like 'a' but exception is thrown if the path exists.
  • 'a+' – Open file for reading and appending. The file is created if it doesn’t exist.
  • 'ax+' – Like 'a+' but exception is thrown if the path exists.
  • 'as' – Opens a file for appending in synchronous mode. The file is created if it does not exist.
  • 'as+' – Opens a file for reading and appending in synchronous mode. The file is created if it does not exist.
  • 'r' – Opens a file for reading. An exception is thrown if the file doesn’t exist.
  • 'r+' – Opens a file for reading and writing. An exception is thrown if the file doesn’t exist.
  • 'rs+' – Opens a file for reading and writing in synchronous mode.
  • 'w' – Opens a file for writing. The file is created (if it does not exist) or overwritten (if it exists).
  • 'wx' – Like 'w' but fails if the path exists.
  • 'w+' – Opens a file for reading and writing. The file is created (if it does not exist) or overwritten (if it exists).
  • 'wx+' – Like 'w+' but exception is thrown if the path exists.

The encoding option is a string that sets the character encoding in the form of the string. The default value is null .

The fd option is the integer file descriptor which can be obtained with the open function and its variants. If the fd option is set, then the path argument will be ignored. The default value is null .

The mode option is the file permission and sticky bits of the file, which is an octal number that is the same as Unix or Linux file permissions. It’s only set if the file is created.

The default value is 0o666. The autoClose option specifies that the file descriptor will be closed automatically. The default value is true . If it’s false , then the file descriptor won’t be closed even if there’s an error. It’s completely up to us to close it autoClose is set to false to make sure there’s no file descriptor leak.

Otherwise, the file descriptor will be closed automatically if there’s an error or end event emitted. The emitClose option will emit the close event when the write stream ends.

The default value is false . The start and end options specifies the beginning and end parts of the file to write.

Everything in between will be written in addition to the start and end . start and end are numbers that are the starting and ending bytes of the file to write.

To create a WriteStream, we can use the createWriteStream like in the following code:

const fs = require("fs");  
const sourceFile = "./files/file.txt";  
const destFile = "./files/newFile.txt";
const readStream = fs.createReadStream(sourceFile);  
const writeStream = fs.createWriteStream(destFile, {  
  flags: "w",  
  encoding: "utf8",  
  mode: 0o666,  
  autoClose: true,  
  emitClose: true,  
  start: 0  
});

readStream.pipe(writeStream);

writeStream.on("open", () => {  
  console.log("Stream opened");  
});

writeStream.on("ready", () => {  
  console.log("Stream ready");  
});

writeStream.on("pipe", src => {  
  console.log(src);  
});

writeStream.on("unpipe", src => {  
  console.log(src);  
});

writeStream.on("finish", () => {  
  console.log("Stream finished");  
});

When we run the code above, we should get something like the following outputted to the screen:

Stream opened  
Stream ready  
ReadStream {  
  _readableState: ReadableState {  
    objectMode: false,  
    highWaterMark: 65536,  
    buffer: BufferList { head: null, tail: null, length: 0 },  
    length: 0,  
    pipes: null,  
    pipesCount: 0,  
    flowing: false,  
    ended: true,  
    endEmitted: true,  
    reading: false,  
    sync: false,  
    needReadable: false,  
    emittedReadable: false,  
    readableListening: false,  
    resumeScheduled: false,  
    paused: false,  
    emitClose: false,  
    autoDestroy: false,  
    destroyed: true,  
    defaultEncoding: 'utf8',  
    awaitDrain: 0,  
    readingMore: false,  
    decoder: null,  
    encoding: null  
  },  
  readable: false,  
  _events: [Object: null prototype] { end: [Function] },  
  _eventsCount: 1,  
  _maxListeners: undefined,  
  path: './files/file.txt',  
  fd: null,  
  flags: 'r',  
  mode: 438,  
  start: undefined,  
  end: Infinity,  
  autoClose: true,  
  pos: undefined,  
  bytesRead: 16,  
  closed: false  
}  
Stream finished

We have the Readable object sent when the pipe event is emitted. Also, we should get content that’s in file.txt in newFile.txt .

WriteStream Events

With a WriteStream, we can listen to the following events. There’s a close event which is emitted when the close event is emitted after the file is written. The open event is emitted when the stream is opened. The file descriptor number fd will be passed with the event when it’s emitted. The ready event is emitted when the WriteStream is ready to be used. It’s fired immediately after the open event is fired.

WriteStreams extend the Writable object, which emits events of its own. The close event is emitted when the stream any of its underlying resources like file descriptors have been closed.

This event indicates that there’re no more events to be emitted from the stream and nothing else will be run. If the emitClose option is set to true when creating the WriteStream then the close event will be emitted.

If a call to the stream.write function returns false , then the drain event will be emitted when writing data to the stream is resumed. The error event is emitted when an error occurred when piping data.

The listener callback function has an error object parameter to get the error information. The stream isn’t closed on error events unless the autoDestroy option is set to true when creating the stream.

After the error event is emitted, then no events other than close should be emitted. The finish event is emitted after the stream.end function is called and all data is flush to the underlying system like a file.

The pipe event is emitted when stream.pipe function is called with a readable stream passed in as an argument . The file specified when creating the ReadStream must exist before piping from it.

The unpipe event is emitted when the stream.unipipe function is called on the readable stream. It’s also emitted when the WriteStream emits an error event when a ReadStreanm is piped to it.

A WriteStream has a few properties. The bytesWritten property indicates the number of bytes being written by the WriteStream so far and doesn’t include data that’s still queued for writing.

The path property is the path of the file the WriteStream is writing to, which is the same as the first argument of the fs.createWriteStream function.

It will be of the same type as whatever we passed into the first argument of fs.createWriteStream . The pending property is a boolean that is true when the underlying file hasn’t been opened, that is, before the ready event is emitted.

By using the fs.createWriteStream function, we created read streams to read a file’s data sequentially and listen to events from a read stream. Since Node.js WriteStreams are descendants of the Writable object, we will also listen to events to it.

We have lots of control of how the write stream is created. We can set the path or file descriptor of the file. Also, we can set the mode of the file to be written and the permission and sticky bit of the file being read.

Also, we can choose to close the streams automatically or not or emit close event automatically.

We get data to a write stream by passing the WriteStream object as an argument of the ReadStream’s pipe function.

Categories
Express JavaScript

Guide to the Express Response Object — More Ways to Send

The Express response object lets us send a response to the client.

Various kinds of responses like strings, JSON, and files can be sent. Also, we can send various headers and status code to the client in addition to the body.

In this article, we’ll look at how to set headers and send status codes with other items, including the set method for setting headers, status for setting response status code, type for setting the Content-Type header value, and the vary method for setting the Vary header value.

Methods

res.set(field [, value])

We can use the set method to set response headers before sending a response.

For example, we can use it as follows:

const express = require('express');  
const path = require('path');  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res, next) => {  
  res.set({  
    'Content-Type': 'text/plain',  
    'Content-Length': '100'  
  })  
    .send();  
})  
app.listen(3000);

Then when we make a request to / , we get that the Content-Length header is set to 100 and the Content-Type is set to text/plain .

Note that we have to call send to send the response.

We can verify this with an HTTP client like Postman.

res.status(code)

We can call the status method to add a status code before sending the response.

For example, we can use it as follows:

const express = require('express');  
const path = require('path');  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res, next) => {  
  res.status(400).send('Bad Request');  
})
app.listen(3000);

Then we get Bad Request displayed and the 400 response code.

res.type(type)

The type method sets the Content-Type HTTP header to the MIME type determined by the mime.lookup() method from the node-mime package for the specified type.

If type contains the / character, then it sets the Content-Type to type .

This method doesn’t send the response.

For example, we can use it as follows:

const express = require('express');  
const path = require('path');  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res) => {  
  res.type('.html').send();  
})  
app.listen(3000);

Then we get that the Content-Type response header has the value text/html; charset=utf-8 .

If we have:

const express = require('express');  
const path = require('path');  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res) => {  
  res.type('.png').send();  
})  
app.listen(3000);

Then we get image/png instead of text/html for the value of Content-Type .

res.vary(field)

The vary method adds the field to the Vary response header if it’s not already there.

For example, we can use it as follows:

const express = require('express');  
const path = require('path');  
const app = express()  
app.use(express.json())  
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res) => {  
  res.vary('User-Agent').send();  
})  
app.listen(3000);

Then we have the Vary response header set to User-Agent .

The Vary header lets us to content negotiation, which is a mechanism for serving different kinds of data with the same URL.

The user agent can specify what’s best for the server.

The Vary header indicates which headers it’s used for content negotiation.

Since we have the Vary header set to User-Agent , our app uses the User-Agent header to serve different kinds of content according to the user agent of the browser.

Conclusion

The set method lets us set headers before sending our response. It takes an object with the response headers that we want to send.

status method is for setting a response status code before sending it. We can chain it with the response body.

The type method is for setting the Content-Type header value. The returned MIME-type is determined by the mime.lookup() method from node-mime .

The vary method for setting the Vary header value. The Vary header is used for content negotiation, which is serving different content according to the field specified by the Vary header’s value with the same URL.

Categories
Angular JavaScript

Accepting User Input with Angular

Angular is a popular front-end framework made by Google. Like other popular front-end frameworks, it uses a component-based architecture to structure apps.

In this article, we’ll look at how to accept user inputs with Angular.

User Input

We can use Angular event bindings to respond to any DOM event.

Many DOM events are triggered by user input. Bindings let us provide a way to get input from users.

For example, we can listen to button clicks as follows:

app.component.ts :

import { Component } from "@angular/core";

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"]  
})  
export class AppComponent {  
  onClickMe() {  
    alert("clicked");  
  }  
}

app.component.html :

<button (click)="onClickMe()">Click me!</button>

In the code above, we have the onClickMe method to display an alert.

Then in app.component.html , we added a button which is bound to the click and calls onClickMe when it’s clicked.

Get User Input From the $event Object

DOM events carry a payload of information that may useful to the component. We can access that information by referencing the $event object.

For example, we can write:

app.component.ts :

import { Component } from "@angular/core";

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"]  
})  
export class AppComponent {  
  keysPressed: string[] = [];  
  onKeyUp(event) {  
    this.keysPressed.push(event.key);  
  }  
}

app.component.html :

<input (keyup)="onKeyUp($event)" />  
<p>{{keysPressed.join(',')}}</p>

In the code above, we have the onKeyUp method of AppComponent which called on the keyup event of input.

In onKeyUp , we push the key that was pressed into the this.keyPressed array.

Then in the template, we call join to combine the strings of the keys that are pressed together.

Type the $event

We can use the KeyboardEvent type to type $event for keyboard events.

We can type the element with the HTMLInputElement type.

For example, we can write the following code:

app.component.ts :

import { Component } from "@angular/core";

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"]  
})  
export class AppComponent {  
  values: string[] = [];  
  onKeyUp(event: KeyboardEvent) {  
    this.values.push((event.target as HTMLInputElement).value);  
  }  
}

app.component.html :

<input (keyup)="onKeyUp($event)" />  
<p>{{values.join(',')}}</p>

In AppComponent above, we set the event to the KeyboardEvent type and casted the event.target to the HTMLInputElement type.

This way, we get auto-complete and so we’re less likely to make mistakes.

However, passing in the whole $event object to the component reveals too many details about the event and so creates tight coupling between the template and the component.

Get User Input From a Template Reference Variable

We can use template reference variables to get input values.

For example, we can do that as follows:

app.component.ts :

import { Component } from "@angular/core";

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"]  
})  
export class AppComponent {}

app.component.html :

<input #box (keyup)="null" />  
<p>{{box.value}}</p>

On the code above, we have the keyup handler set to null and we added the #box reference variable to the input box.

Then we render the value of the #box input by referencing box.value .

When we type in something into the input box, we’ll see the value displayed in the p element.

This is better than using the $event object to get the value since it doesn’t we don’t have to access the $event object to get the value. Key Event Filtering

We can listen for specific keypresses in an element by specifying the key with the key attribute.

For example, if we want to listen to presses of the Enter key, we can write the following:

app.component.html :

import { Component } from "@angular/core";

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"]  
})  
export class AppComponent {  
  onEnter(value) {  
    alert(value);  
  }  
}

app.component.html :

<input #box (keyup.enter)="onEnter(box.value)" />

In the code above, we have the onEnter method in AppComponent that takes the value entered into the input box.

Then in app.component.html , we added the #box template variable to the input and have:

(keyup.enter)="onEnter(box.value)"

to listen to keypresses of the Enter key and pass in the value entered into the input to display the alert by calling onEnter with the value passed in.

On Blur

We can listen to the blur event of an element by passing an event listener to an element.

For example, we can write:

app.component.ts :

import { Component } from "@angular/core";

@Component({  
  selector: "app-root",  
  templateUrl: "./app.component.html",  
  styleUrls: ["./app.component.css"]  
})  
export class AppComponent {  
  value: string;  
  update(value) {  
    this.value = value;  
  }  
}

app.component.html :

<input #box (blur)="update(box.value)" />  
<p>{{value}}</p>

In the code above, we add the #box template variable to the input box and we added a blur event listener by setting (blur) to the update method in AppComponent .

The update method takes an inputted value and sets it to this.value so we can display it in our template.

Then when we type in something into the input and then move the cursor away from the input, we’ll see the value displayed in the p element.

Conclusion

We can handle user inputs by listening to various event listeners.

To get the event object emitted by the event, we can reference the $event object.

To make getting inputted values easier, we can add a template reference variable to the element in the template and then get the properties we want from it.

Categories
JavaScript Vue

How to Conditionally Render Elements in Vue

Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.

In this article, we’ll look at various ways to render items conditionally on the screen with Vue.js by using the v-show directive.

Also, we’ll look at the performance implications of combining v-if and v-for is various ways.

v-show

The v-show directive is used to show something when the expression we passed into it is truthy.

For example, we can use it as follows:

<h1 v-show="show">Hi</h1>

The difference between v-show and v-if are that v-show elements remain in the DOM even though is hidden.

On the other hand, v-if elements are hidden by removing them from the DOM.

Also, v-if removes event listeners and child components inside conditional blocks are destroyed if they’re hidden and recreated when v-if ‘s expression is truthy.

v-if elements are also different in that if the condition is falsy during conditional render, it won’t do anything. It won’t be rendered until the expression becomes truthy.

v-if has higher toggling than v-show since DOM manipulating and attaching event listeners have to be done when things are toggled.

Therefore, if things need to be toggled often, v-show is more efficient.

v-if with v-for

v-for has higher priority than v-if if they’re used together.

However, we shouldn’t use them together because of the higher precedence of v-for over v-if .

If we want to filter some elements out when we render items from an array, we should use a computed property.

If we only render a small fraction of array elements, it has to iterate over the entire list and then check if the expression we set it truthy.

For example, the following JavaScript and HTML code:

src/index.js :

new Vue({  
  el: "#app",  
  data: {  
    persons: ["Joe", "Jane", "Mary"]  
  }  
});

index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  
  </head>  <body>  
    <div id="app">  
      <div v-for="person in persons" v-if='person !== "Joe"'>  
        {{person}}  
      </div>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

is not very efficient since every time the loop is rendered, Vue has to iterate through every element and then check if person !== “Joe” is true .

Instead, we should use a computed property as follows:

src/index.js :

new Vue({  
  el: "#app",  
  data: {  
    persons: ["Joe", "Jane", "Mary"]  
  },  
  computed: {  
    personsWithoutJoe() {  
      return this.persons.filter(p => p !== "Joe");  
    }  
  }  
});

index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  
  </head>  <body>  
    <div id="app">  
      <div v-for="person in personsWithoutJoe">  
        {{person}}  
      </div>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

The code above is more efficient because personsWithoutJoe is only recomputed when persons change.

Also, only the items in personsWithoutJoe is iterated through during render, so v-for doesn’t have to loop through all the items.

There’s also less logic in the template, which keeps it clean. Maintenance is much easier.

We can also get performance benefits from moving v-if to the parent element that has the v-for , so whatever’s inside is only rendered when the condition is met.

For example, if we have:

src/index.js :

new Vue({  
  el: "#app",  
  data: {  
    persons: ["Joe", "Jane", "Mary"],  
    show: false  
  }  
});

index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  
  </head>  <body>  
    <div id="app">  
      <div v-if="show">  
        <div v-for="person in persons">  
          {{person}}  
        </div>  
      </div>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

Then nothing is rendered since show is false . Vue doesn’t have to do the work to look at whatever’s inside.

This is much better than:

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  
  </head>  <body>  
    <div id="app">  
      <div v-for="person in persons" v-if="show">  
        {{person}}  
      </div>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

In the code above, Vue has to loop through each entry and check if the condition in the v-if returns a truthy value.

As we can see, even though the code is only slightly different, but the performance implications are big.

Conclusion

v-show is similar to v-if , except that items with v-show stays in the DOM no matter if it’s shown or not.

Also, we should be careful when we combine v-for and v-if .

First, v-for takes precedence over v-if if applied to the same element.

Also, we shouldn’t use them on the same element since Vue has to check each element for v-if ‘s condition in every iteration.

If we want to render a filtered list, we should use a computed property.

If we want to check if we should render the whole array, we should move v-if to the parent of the element with v-for , so that if v-if ‘s condition is falsy, then Vue won’t render the items in there.

Categories
Express JavaScript Nodejs

Add Timeout Capability to Express Apps with connect-timeout

To prevent requests from taking too long, it’s a good idea to have a maximum processing time for requests.

We can do this by making requests that take too long to time out. The connect-timeout middleware can help us do this.

In this article, we’ll look at how to use it to implement time out features in our app.

One Catch

This middleware sends a timeout response back to the client if a request exceeds the maximum time that we specify.

However, in the background, it’ll continue to run whatever was running before the request timed out.

Resources like CPU and memory will continue to be used until the process terminates.

We may need to end the process and free up any resources that it was using.

Usage

The timeout function takes 2 arguments. The first is the time for the maximum time for the request to process, and the second is an options object.

Time

The time is either a number in milliseconds or a string accepted by the ms module.

On timeout, req will emit timeout .

Options

The options object takes an optional object that can have the following property:

  • respond — controls if this module will response in the form of forwarding an error. If it’s true , the timeout error is passed to the next so that we may customize the response behavior. The error has a timeout property and status code 503. The default is true .

req.clearTimeout()

The clearTimeout method clears the timeout on the request and it won’t fire for this request in the future.

req.timedout

A boolean that is true if timeout is fired and false otherwise.

Example

We can use it as follows as top-level middleware. We have to stop the flow to the next middleware if the request timed out so they won’t run.

For example, we can write:

const express = require('express');  
const bodyParser = require('body-parser');  
const timeout = require('connect-timeout');  
const app = express();  
const haltOnTimedout = (req, res, next) => {  
  if (!req.timedout) {  
    next();  
  }  
}  
app.use(timeout('5s'))  
app.use(bodyParser.json({ extended: true }))  
app.use(haltOnTimedout)
app.get('/', (req, res) => {  
  res.send('success');  
})
app.listen(3000);

Then our endpoints will time out after 5 seconds and only allow to proceed beyond the bodyParser middleware if the request hasn’t timed out.

We can check time out by adding setTimeout to our route handler as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const timeout = require('connect-timeout');  
const app = express();  
const haltOnTimedout = (req, res, next) => {  
  if (!req.timedout) {  
    next();  
  }  
}  
app.use(timeout('5s'))  
app.use(bodyParser.json({ extended: true }))  
app.use(haltOnTimedout)
app.get('/', (req, res) => {  
  setTimeout(() => {  
    res.send('success');  
  }, Math.random() * 7000);  
})
app.listen(3000);

The some requests will time out and get us a 503 response.

We can catch the error and handle it ourselves as follows:

const express = require('express');  
const bodyParser = require('body-parser');  
const timeout = require('connect-timeout');  
const app = express();  
const haltOnTimedout = (req, res, next) => {  
  if (!req.timedout) {  
    next();  
  }  
}
app.use(timeout('5s'))  
app.use(bodyParser.json({ extended: true }))  
app.use(haltOnTimedout)
app.get('/', (req, res, next) => {  
  setTimeout(() => {  
    if (req.timedout) {  
      next();  
    }  
    else {  
      res.send('success');  
    }  
  }, Math.random() * 7000);  
})
app.use((err, req, res, next) => {  
  res.send('timed out');  
})
app.listen(3000);

In the setTimeout callback, we check the req.timedout property and called next() if it times out so that it’ll go to our error handler.

Note that we have the error handler after our route so calling next will go to our error handler.

We should get timed out if our request timed out instead of the error message and stack trace.

Conclusion

We can use the connect-timeout middleware to implement time out functionality for our routes.

This sends a 503 response if a request times out, but it doesn’t clear all the resources that’s being used for the request and end the process that’s still running.

We can check if a request has timed out with the req.timedout property.

Finally, we can catch the error by adding our own error handler after our routes and calling next .