<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Valentin Kuharic</title>
    <description>The latest articles on DEV Community by Valentin Kuharic (@valentinkuharic).</description>
    <link>https://dev.to/valentinkuharic</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F767494%2F1ef0e052-b06b-47ac-a806-ad3333dd0138.png</url>
      <title>DEV Community: Valentin Kuharic</title>
      <link>https://dev.to/valentinkuharic</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/valentinkuharic"/>
    <language>en</language>
    <item>
      <title>Want to learn fast? Then "reinvent the wheel" all the time.</title>
      <dc:creator>Valentin Kuharic</dc:creator>
      <pubDate>Wed, 23 Aug 2023 15:00:39 +0000</pubDate>
      <link>https://dev.to/valentinkuharic/want-to-learn-fast-then-reinvent-the-wheel-all-the-time-4nfg</link>
      <guid>https://dev.to/valentinkuharic/want-to-learn-fast-then-reinvent-the-wheel-all-the-time-4nfg</guid>
      <description>&lt;p&gt;The job of a software developer can be summarized into two words: constantly evolving. Anti-static. The nature of software demands it since modern programs, apps, and websites require us to use a plethora of abstraction layers and tools that we can't always know how they really work. Each tool or layer we bring into our environment abstracts some part of the development process behind its API that we will then use. This is a normal process with the fantastic benefit of enabling the developer to create complex, stable, and beautiful applications and tools that would otherwise require whole teams of experts just a couple of years ago to construct. This phenomenon has a downside that we must be aware of, especially in the modern web world. So many processes and behaviors get abstracted that we begin to learn the APIs of those tools, not the programming itself.&lt;/p&gt;

&lt;p&gt;Most of the newcomers to the world of software development begin their journey in the web world. The beginnings are rough and hard, and the front end is a great starting point since it provides visual feedback and is the most rewarding part for most people. After spending the humble beginning writing calculators, managing arrays with loops, or handling input and output to the console, the ability to create websites so quickly feels ground-breaking. Naturally, this progress leads a new developer to the UI libraries and frameworks of the modern day: React, Angular, and such.&lt;/p&gt;

&lt;p&gt;We tend to forget how amazing these tools are and just how much they speed development up. A decent React developer can easily take a Figma design file and recreate the UI and interactivity without breaking a sweat. They help us handle the UI, updating state, routing, and more, and they introduce their APIs to do so. In a rush to get a job and start earning money, this makes new, fresh, and inexperienced developers rush to these tools, sparking the numerous "What is the best frontend framework to learn" debates.&lt;/p&gt;

&lt;p&gt;This has the often forgotten consequence of new developers learning frameworks, not programming itself. They learn the APIs of their tools and how to use them, get a job, and then struggle to keep up with the more complex codebases. Writing UIs and connecting them with backends usually works well, but problems arise when the apps get complicated to the point where custom state management practices are required, reducing the number of requests to the backend should be tackled, or decoupling of the presentation layer from the other code needs to be done, or even rewriting the UI from one library to another. This inevitably brings challenges to the developer, where a clear lack of competence gets shown and the developer struggles to keep up. The pace of modern development doesn't help, making it hard to, between a full-time job and other parts of life, find enough time and energy to try to work on one's personal projects. It is my own opinion that most fresh developers struggle with this, myself included. It's a balancing act all of us need to manage.&lt;/p&gt;

&lt;p&gt;Software is not easy, and between college and Udemy tutorials there is a lot of sweat, failed projects, and keystrokes needed to grasp the concepts and get stuff done. This brings me to the title of this post: reinvent the wheel. I constantly hear the advice "Stop going through tutorials, think of an idea, and start working on it", which is the best way to learn in my opinion. But there is an addition I'd like to recommend - start reinventing the wheel, which will further deepen your understanding of your codebase.&lt;/p&gt;

&lt;p&gt;Maybe you're using the RxJs library to aid with state management in your front-end project. It's quite a complex library and takes some brain power to grasp the concepts and start using it well. Why not try and recreate its reactive primitives? It's easier than it seems, and the new-found intuition and understanding will reshape your thinking about RxJs. It's incredible how much this practice changes your perspective. They don't say "To fix it, you first need to know how it works" with no reason. Maybe you use Express for writing backend apps in Node. Have you ever wondered how the routes work? What's happening underneath the pretty syntax?&lt;/p&gt;

&lt;p&gt;With the power of understanding the hidden layers comes the benefit of making fewer bugs, quicker debugging, and even the ability to modify some behavior otherwise inaccessible. If one has the time, I strongly recommend to try and tackle an unknown variable in your toolset, and by recreating just the most basic parts of it, you may come out a stronger engineer on the other side.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Shielding Your Instances with Private Subnets on AWS</title>
      <dc:creator>Valentin Kuharic</dc:creator>
      <pubDate>Tue, 22 Aug 2023 10:00:05 +0000</pubDate>
      <link>https://dev.to/valentinkuharic/building-a-secure-aws-network-protecting-instances-with-private-subnets-4h36</link>
      <guid>https://dev.to/valentinkuharic/building-a-secure-aws-network-protecting-instances-with-private-subnets-4h36</guid>
      <description>&lt;h2&gt;
  
  
  📜 Table of contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
Building a Secure AWS Network: Protecting Instances with Private Subnets

&lt;ul&gt;
&lt;li&gt;Table of contents&lt;/li&gt;
&lt;li&gt;1. Introduction&lt;/li&gt;
&lt;li&gt;Disclaimer&lt;/li&gt;
&lt;li&gt;2. Introduction to VPCs and deploying a basic instance&lt;/li&gt;
&lt;li&gt;2.1. VPCs&lt;/li&gt;
&lt;li&gt;
2.2. CIDR blocks, subnets and security groups

&lt;ul&gt;
&lt;li&gt;2.2.1. CIDR blocks&lt;/li&gt;
&lt;li&gt;2.2.2. Subnets&lt;/li&gt;
&lt;li&gt;2.2.3. Security groups&lt;/li&gt;
&lt;li&gt;2.2.4. Route tables&lt;/li&gt;
&lt;li&gt;2.2.5. Internet gateway&lt;/li&gt;
&lt;li&gt;2.2.6. DNS resolution&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

2.3. Setting up a basic deployment

&lt;ul&gt;
&lt;li&gt;2.3.1. Creating the VPC&lt;/li&gt;
&lt;li&gt;2.3.2. Enabling DNS resolution&lt;/li&gt;
&lt;li&gt;2.3.3. Creating the subnets&lt;/li&gt;
&lt;li&gt;2.3.4. Making the subnets public (route tables and Internet gateways)&lt;/li&gt;
&lt;li&gt;2.3.3. Initial VPC setup&lt;/li&gt;
&lt;li&gt;2.3.2. Creating our managed backend application&lt;/li&gt;
&lt;li&gt;2.3.3. Creating our database instance&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;2.3.4. Basic deployment visualisation&lt;/li&gt;

&lt;li&gt;3. Challenges of exposing instances to the Internet&lt;/li&gt;

&lt;li&gt;

3.1. Principle of least privilege

&lt;ul&gt;
&lt;li&gt;3.1.1. Explanation&lt;/li&gt;
&lt;li&gt;3.1.2. Examples&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;4. Fixing the mistakes (new architecture)&lt;/li&gt;

&lt;li&gt;

4.1. Backend: Load-balancing the backend + NAT

&lt;ul&gt;
&lt;li&gt;4.1.1. Approach&lt;/li&gt;
&lt;li&gt;4.1.2. Creating the subnets&lt;/li&gt;
&lt;li&gt;4.1.3. Creating and configuring the environment&lt;/li&gt;
&lt;li&gt;4.1.4. Backend design visualisation&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

4.2. Database: Protecting the database with a jump host + security group access rules

&lt;ul&gt;
&lt;li&gt;4.2.1. Creating subnets&lt;/li&gt;
&lt;li&gt;4.2.2. Creating the database instance&lt;/li&gt;
&lt;li&gt;4.2.3. Creating the jump host&lt;/li&gt;
&lt;li&gt;4.2.4. Connecting to the database&lt;/li&gt;
&lt;li&gt;4.2.5. Configuring traffic rules&lt;/li&gt;
&lt;li&gt;4.2.5.1. Jump host security group&lt;/li&gt;
&lt;li&gt;4.2.5.2. Database instance security group&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;4.3. Final architecture visualisation&lt;/li&gt;

&lt;li&gt;6. Conclusion&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  📝 1. Introduction
&lt;/h2&gt;

&lt;p&gt;This post will cover various methods for enhancing security for AWS instances through the strategic use of public and private subnets. We'll explore the foundational concepts of Virtual Private Clouds (VPCs) and demonstrate how you can harness the capabilities of a VPC in conjunction with various network nodes to shield your systems from external threats. Later chapters will cover various scenarios, pinpointing potential challenges and their solutions in certain configurations.&lt;/p&gt;

&lt;p&gt;Note that this article will focus exclusively on the communication channels between various network areas and nodes, as well as the rules governing interactions between the internet and the private network. Vulnerabilties stemming from the applications themselves or any other architectural issues will not be covered.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤚 Disclaimer
&lt;/h2&gt;

&lt;p&gt;This article will touch upon several advanced techniques in computer networking that readers should have a foundational understanding of to fully grasp the content. While we will provide explanation for most basic concepts and provide definitions, the reader should familiarize themselves with any new concepts they come across to fully understand the content.&lt;/p&gt;

&lt;p&gt;Constructing your architecture incrementally often proves more efficient and less time-consuming than striving for a comprehensive build right from the get go.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Introduction to VPCs and deploying a basic instance
&lt;/h2&gt;

&lt;p&gt;ℹ️ &lt;strong&gt;Note!&lt;/strong&gt;&lt;br&gt;
Basic knowledge of computer networks is required.&lt;/p&gt;
&lt;h3&gt;
  
  
  2.1. VPCs
&lt;/h3&gt;

&lt;p&gt;VPC (Virtual Private Cloud) is a virutal private network you own via your AWS account. In contrast to real, physical machines, routers and switches it is virtually constructed, but the concepts remain the same. &lt;/p&gt;

&lt;p&gt;VPCs can be thought of as real networks with the same features by which they provide a structured way to deploy your AWS instances. By default, a VPC is logically isolated from the Internet effectively functioning as a separate network.&lt;/p&gt;

&lt;p&gt;The AWS network is a collection of Availability Zones, which are physically represented as data centers. They are interconnected and they form the AWS network. These AZs are then grouped into regions. When we put all this together, we can visually represent the different areas and overlaps like so:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr5tieeitqlwwdrpxhbcc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr5tieeitqlwwdrpxhbcc.png" alt=" " width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Visualisation shows a sample AWS region composed of three AZs. Inside the regions we have our private VPC that's spanning across three AZs (we can configure our VPC to reach one or more AZs). Using the internet gateway we can enable communication with the Internet (more on this later). &lt;/p&gt;
&lt;h3&gt;
  
  
  2.2. CIDR blocks, subnets and security groups
&lt;/h3&gt;
&lt;h4&gt;
  
  
  2.2.1. CIDR blocks
&lt;/h4&gt;

&lt;p&gt;The basic concept of computer networks is that each node in a network is assigned a unique address by which we recognize it as a node. Just as each house in our street has a house number, each node in a computer network has a so-called &lt;a href="https://en.wikipedia.org/wiki/IP_address" rel="noopener noreferrer"&gt;IP address&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Armed with that knowledge, we can represent the scope of our private network as a range of IP addresses. A good analogy would be that in a street we would assign numbers to houses from 20-44, so the same logic would apply to networks - a VPC has a range of IP addresses.&lt;/p&gt;

&lt;p&gt;ℹ️ &lt;strong&gt;Note!&lt;/strong&gt;&lt;br&gt;
Basic knowledge of IP addresses is required. Use the following &lt;a href="https://docs.oracle.com/cd/E19504-01/802-5753/planning3-18471/index.html" rel="noopener noreferrer"&gt;link&lt;/a&gt; to learn how IP addresses are comprised.&lt;/p&gt;

&lt;p&gt;To keep things simple, we'll take only IPv4 addresses into account. Each IPv4 address consists of four 8 bit fields. Meaning the smallest address is 0.0.0.0 and the largest one is 255.255.255.255.&lt;/p&gt;

&lt;p&gt;This separation of 4 distinct parts is very useful since we can easily subdivide our total IP range into sections. For example, we can say that some abstract distinct section of our network will have IP address range between 24.24.24.0 and 24.24.24.255. In this case the number of addresses this section has been assigned is 256 addresses.&lt;/p&gt;

&lt;p&gt;We need a simple, formal way of representing these ranges. Our written example is fine, but we can condense this information into a structured, standardized format that computers can also read.&lt;/p&gt;

&lt;p&gt;A CIDR block is a notation we can use to represent the IP ranges. Let's take a look at an example of a CIDR block:&lt;/p&gt;

&lt;p&gt;$$25.25.25.0/24$$&lt;/p&gt;

&lt;p&gt;denotes an IP range from 25.25.25.0 to 25.25.25.255.&lt;/p&gt;

&lt;p&gt;The $/24$ suffix indicates the count of consecutive leading 1-bits (from left to right) in the network mask. This just means the number of bits that are fixed.&lt;/p&gt;

&lt;p&gt;Finally, we can now define our private network space with a CIDR block that has 16 static bits. An example would be:&lt;/p&gt;

&lt;p&gt;$$192.168.0.0/16$$&lt;/p&gt;
&lt;h4&gt;
  
  
  2.2.2. Subnets
&lt;/h4&gt;

&lt;p&gt;So far we have defined our VPC range. Referencing the image of above of defining a sample VPC space, we can notice different "subnets" inside the VPC.&lt;/p&gt;

&lt;p&gt;Subnets are a powerful concept of dividing our network into distinct parts. This is extremely useful since it helps us organize our nodes inside the network. &lt;/p&gt;

&lt;p&gt;Let us consider an example where we have multiple database nodes and multiple application nodes in our network. We will assign each node in the network its own rules for accessing other parts of the network. As our network expands this would become exponentially more cumbersome and difficult to manage.&lt;/p&gt;

&lt;p&gt;Subnets allow us to set and define these rules of communication and access to a specific range of our network; then all nodes inside the subnet will adhere to these rules. This greatly simplifies managing our nodes.&lt;/p&gt;
&lt;h4&gt;
  
  
  2.2.3. Security groups
&lt;/h4&gt;

&lt;p&gt;In addition to subnets, another pivotal aspect of securing our AWS architecture is the implementation of Security Groups. While subnets manage network segmentation, security groups take on the role of controlling inbound and outbound traffic at the instance level. They act as virtual firewalls that regulate the traffic allowed to and from instances associated with them.&lt;/p&gt;

&lt;p&gt;Security groups operate based on rules that explicitly permit or deny specific traffic flows. These rules can be defined in terms of allowed IP addresses, port ranges, and protocols. Unlike network access control lists (ACLs), which operate at the subnet level, security groups are associated with individual instances.&lt;/p&gt;

&lt;p&gt;By configuring security groups, you can create a strong defense mechanism to safeguard your instances from unauthorized access and potential security breaches. As you continue to explore the intricacies of AWS security, a comprehensive understanding of both subnets and security groups will be instrumental in designing a well-protected and robust environment for your applications.&lt;/p&gt;

&lt;p&gt;At this point we have introduced the vital tools of controlling network ranges and assigning communication rules to those sub-ranges (subnets) and to the individual nodes themselves. Later we will apply these concepts on real world examples to see how to effectively use them to create a secure network.&lt;/p&gt;
&lt;h4&gt;
  
  
  2.2.4. Route tables
&lt;/h4&gt;

&lt;p&gt;In the vast networking landscape of AWS, route tables play a central role in directing traffic flow. They contain a set of rules, called routes, that determine how traffic is forwarded between subnets, the internet, and other connected networks.&lt;/p&gt;

&lt;p&gt;Each subnet in a VPC must be associated with a route table, which dictates the traffic routing for the subnet. A VPC is created with a main route table by default, but additional custom route tables can also be created. When a subnet doesn't have an explicitly associated route table, it falls back to the main route table.&lt;/p&gt;

&lt;p&gt;Configuring the route table accurately ensures that your network's traffic reaches its intended destination efficiently. For instance, if you want a subnet to communicate with the internet, you would modify the route table associated with that subnet to include a route to an internet gateway.&lt;/p&gt;
&lt;h4&gt;
  
  
  2.2.5. Internet gateway
&lt;/h4&gt;

&lt;p&gt;An Internet Gateway serves as a critical bridge, enabling communication between resources in your VPC and the internet. It offers a two-way portal: it allows the internet to access your instances (when permitted) and lets your instances access the internet.&lt;/p&gt;

&lt;p&gt;To facilitate this connectivity, you must attach an Internet Gateway to your VPC and then configure the appropriate route in the associated route table. With this setup, EC2 instances in your VPC can directly communicate with the internet, as long as they have an Elastic IP or Public IP.&lt;/p&gt;

&lt;p&gt;Remember, while the Internet Gateway paves the way for internet connectivity, the actual accessibility is governed by security groups and network ACLs, ensuring a layered approach to security.&lt;/p&gt;
&lt;h4&gt;
  
  
  2.2.6. DNS resolution
&lt;/h4&gt;

&lt;p&gt;The Domain Name System (DNS) translates user-friendly domain names (e.g., "&lt;a href="http://www.example.com" rel="noopener noreferrer"&gt;www.example.com"&lt;/a&gt;) into IP addresses that machines understand. Within a VPC in AWS, DNS resolution is automatically enabled, allowing instances to resolve domain names to their corresponding IP addresses. When EC2 instances are launched, they are assigned both private and public DNS hostnames, provided they're in a subnet set to assign public IPs. Keeping DNS resolution and hostnames enabled in a VPC is crucial for many applications, especially those dependent on DNS for communication.&lt;/p&gt;

&lt;p&gt;🚨 &lt;strong&gt;Warning!&lt;/strong&gt;&lt;br&gt;
We have covered these concepts on a high-level and their implementation in a real AWS network are more complicated and introduce various little rules of application. In the later chapters we will create a real deployment and we will cover some of these, but I strongly recommend that you try to create these rules yourself. Be aware that full network configuration contains more rules and concepts.&lt;/p&gt;
&lt;h3&gt;
  
  
  2.3. Setting up a basic deployment
&lt;/h3&gt;

&lt;p&gt;Let's create a simple deployment containing a database and a backend application.&lt;/p&gt;
&lt;h4&gt;
  
  
  2.3.1. Creating the VPC
&lt;/h4&gt;

&lt;p&gt;We'll ignore the default VPC and create our own. We'll set our CIDR block as 24.24.0.0/24 as shown on the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdym0qabi3oks6ie378pg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdym0qabi3oks6ie378pg.png" alt=" " width="800" height="607"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  2.3.2. Enabling DNS resolution
&lt;/h4&gt;

&lt;p&gt;Enable &lt;em&gt;DNS resolution&lt;/em&gt; and &lt;em&gt;DNS hostnames&lt;/em&gt; in the VPC settings.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fluuzz9v6m933t44xqizw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fluuzz9v6m933t44xqizw.png" alt=" " width="800" height="237"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxbw07tlevv0e1x1dmf9b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxbw07tlevv0e1x1dmf9b.png" alt=" " width="800" height="788"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  2.3.3. Creating the subnets
&lt;/h4&gt;

&lt;p&gt;After creating the VPC we'll create just one public subnet where our instances will live. We'll use CIDR block 24.24.1.0/24.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2c9jmp1ny9tq9u3by7u2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2c9jmp1ny9tq9u3by7u2.png" alt=" " width="800" height="679"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  2.3.4. Making the subnets public (route tables and Internet gateways)
&lt;/h4&gt;

&lt;p&gt;By default, all created subnets are private since they don't have access to the Internet. This is due to the default route table, which sets the communication rules for the subnet.&lt;/p&gt;

&lt;p&gt;Firstly, let's create an Internet Gateway and assign it to our VPC.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Felivee0yf1vc0ujxiu3d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Felivee0yf1vc0ujxiu3d.png" alt=" " width="800" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxw81amvjzzq278b2201k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxw81amvjzzq278b2201k.png" alt=" " width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqca8kwsoejx0i7jfwbk6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqca8kwsoejx0i7jfwbk6.png" alt=" " width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now our VPC has access to traffic from the Internet.&lt;/p&gt;

&lt;p&gt;Create a new route table. We will associate this route table with the subnets we want to make public, so let's set the ruleset to the following traffic rules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Access to all space inside VPC&lt;/li&gt;
&lt;li&gt;Access to the internet gateway&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw9w4tza7x41hh5ihpnqo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw9w4tza7x41hh5ihpnqo.png" alt=" " width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj1ckvvl92appsnmgg73f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj1ckvvl92appsnmgg73f.png" alt=" " width="800" height="231"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the nodes inside the subnet can access traffic from the Internet.&lt;/p&gt;
&lt;h4&gt;
  
  
  2.3.3. Initial VPC setup
&lt;/h4&gt;

&lt;p&gt;So far, we have the following configuration:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8y3khtysq35wyps1b70s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8y3khtysq35wyps1b70s.png" alt=" " width="800" height="510"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  2.3.2. Creating our managed backend application
&lt;/h4&gt;

&lt;p&gt;Let's create our managed backend instances. The node itself that will live in our VPC is a Linux EC2 instance, but we will use Elastic Beanstalk service to manage our instances.&lt;/p&gt;

&lt;p&gt;ℹ️ &lt;strong&gt;Note!&lt;/strong&gt;&lt;br&gt;
Elastic Beanstalk is an AWS service for managing and configuring various other AWS services, mainly used to orchestrate Linux machines. Learn more about it &lt;a href="https://aws.amazon.com/elasticbeanstalk/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Select the prefered platform, in this case &lt;a href="https://nodejs.org/en" rel="noopener noreferrer"&gt;Node&lt;/a&gt; will be used.&lt;/p&gt;

&lt;p&gt;We'll configure it to deploy our instances inside our public subnet. Make sure to select the proper VPC and subnet. Since we'll directly serve traffic to our instance, make sure to check the &lt;em&gt;Public IP address&lt;/em&gt; box to assign a public IP to our instance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe72gmupy8j7jt9n6ttgv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe72gmupy8j7jt9n6ttgv.png" alt=" " width="800" height="1857"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F43ps722y86zedbi50c7v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F43ps722y86zedbi50c7v.png" alt=" " width="800" height="668"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After finishing the configuration wizard, Elastic Beanstalk will spin up and configure our instances. Find the URL in the environment details screen to access the application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7imrmxnkj95aau5oxcl5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7imrmxnkj95aau5oxcl5.png" alt=" " width="800" height="577"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is how the web page should look like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdtp6u6k8k5hy5sazu4cl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdtp6u6k8k5hy5sazu4cl.png" alt=" " width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚨 &lt;strong&gt;Warning!&lt;/strong&gt;&lt;br&gt;
You may possibly encounter an issue while deploying the environment with misconfigured service roles. Take a look at this &lt;a href="https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/iam-instanceprofile.html" rel="noopener noreferrer"&gt;link&lt;/a&gt; for more information. &lt;strong&gt;Dont forget to select the instance profile!&lt;/strong&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  2.3.3. Creating our database instance
&lt;/h4&gt;

&lt;p&gt;To demonstrate a basic deployment of a database, we will deploy an instance running a relational database software. AWS provides a service for doing exactly that, called RDS (Relational Database Service). RDS wizard requires that RDS instances live in a subnet spread across two availability zones. Specifically we're required to create a &lt;a href=""&gt;subnet group&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So far we have created only one public subnet. Navigate to the VPC service and create another public subnet. &lt;strong&gt;Make sure it's placed in a different AZ compared to the first public subnet!&lt;/strong&gt; Now that we have two public subnets in different AZs, navigate to RDS service and create a database subnet group that includes these two subnets.&lt;/p&gt;

&lt;p&gt;🚨 &lt;strong&gt;Warning!&lt;/strong&gt;&lt;br&gt;
Remember to assign the correct route table to the subnet, otherwise no traffic from the Internet can pass through to the instance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fugdstluu83navqdt61ov.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fugdstluu83navqdt61ov.png" alt=" " width="800" height="939"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frud8f2htemjmxwerephv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frud8f2htemjmxwerephv.png" alt=" " width="800" height="1322"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we're ready to finally create the database instance. Navigate to the RDS service and launch the &lt;em&gt;instance creation wizard&lt;/em&gt;. Make sure to properly configure the connectivity settings, including the correct VPC and subnet group. Make sure to enable &lt;em&gt;Public access&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;ℹ️ &lt;strong&gt;Note!&lt;/strong&gt;&lt;br&gt;
For testing purposes I recommend using the &lt;em&gt;free tier&lt;/em&gt; preset for instance class and storage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl1ber5t4mrx69v4cy2gq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl1ber5t4mrx69v4cy2gq.png" alt=" " width="800" height="1313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fshu2h9en5uy9jj2hkmy2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fshu2h9en5uy9jj2hkmy2.png" alt=" " width="800" height="1230"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fopnsgifza97vhijstz1x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fopnsgifza97vhijstz1x.png" alt=" " width="800" height="1429"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  2.3.4. Basic deployment visualisation
&lt;/h3&gt;

&lt;p&gt;So far, we have created the following configuration:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faiw55xa6r6ictwlvbi00.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faiw55xa6r6ictwlvbi00.png" alt=" " width="800" height="661"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Challenges of exposing instances to the Internet
&lt;/h2&gt;

&lt;p&gt;Our current deployment is valid and works. But when we're designing a system for a production application we must always take security into account. With enough traffic we will eventually encounter malicious users and minimizing potential security risks is a must.&lt;/p&gt;
&lt;h3&gt;
  
  
  3.1. Principle of least privilege
&lt;/h3&gt;
&lt;h4&gt;
  
  
  3.1.1. Explanation
&lt;/h4&gt;

&lt;p&gt;The Principle of Least Privilege (PoLP) dictates that in a computing environment, all nodes, modules, processes, users, or programs should have access only to the precise information required to execute their tasks. By confining privileges and access rights, we inherently limit the potential vulnerabilities of our system. This is a very powerful concept for minimizing possible attack surfaces our system design might leave open.&lt;/p&gt;

&lt;p&gt;Imagine a network comprising several nodes. If an attacker compromises one node, the extent of their reach largely depends on the privileges associated with that node.  Considering the principle of least privilege and applying it to our network, the intruder's access is limited, since they can potentially access only a minimal amount of information. This contrasts with a scenario where nodes have unrestricted access, granting the attacker access to the entirety of our network.&lt;/p&gt;

&lt;p&gt;This idea can be taken as far as you want; for instance, you can specify rules for read-only or write-only actions.&lt;/p&gt;
&lt;h4&gt;
  
  
  3.1.2. Examples
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;User Accounts on Operating Systems&lt;/strong&gt;: On most operating systems, there are user accounts with varying privileges. Typically, there are administrator accounts with full system access and standard user accounts with limited access. If a standard user account is compromised, the attacker can't make system-wide changes. This limitation is due to the PoLP; the standard account only has the necessary privileges to run applications and not to modify system settings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Database Management&lt;/strong&gt;: In a database system, not all users need the ability to edit or delete tables. Some might only require read-only access, while others might need more comprehensive permissions for data entry. By tailoring access to individual roles, you can ensure that even if a read-only account gets compromised, the attacker cannot alter the database's data or structure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Web Applications&lt;/strong&gt;: Consider a web application where users can view, post, and edit content. While every user can view posts, perhaps only the original poster can edit or delete their own content. Implementing the PoLP ensures that even if a user's session is hijacked, the malicious actor can only affect the content associated with that specific user and not content from other users.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. Fixing the mistakes (new architecture)
&lt;/h2&gt;

&lt;p&gt;So far we have created a working deployment and we have explained the security risks associated with it. Now we'll introduce new concepts in computer networking and apply them to create a secure environment for our applications. We will be sticking to an example of an application deployment and a database deployment.&lt;/p&gt;
&lt;h3&gt;
  
  
  4.1. Backend: Load-balancing the backend + NAT
&lt;/h3&gt;
&lt;h4&gt;
  
  
  4.1.1. Approach
&lt;/h4&gt;

&lt;p&gt;Our current deployment consists of a Linux machine with a public IP, directly accessible from the internet. We aim to enhance its security by placing it within a private network. Instead of direct access, we'll introduce a gatekeeper - in our case, a &lt;a href="https://en.wikipedia.org/wiki/Load_balancing_(computing)" rel="noopener noreferrer"&gt;load balancer&lt;/a&gt;  - that mediates communication between the internet and our private machine.&lt;/p&gt;

&lt;p&gt;We'll set up an Elastic Beanstalk environment to launch machines in a private subnet running our sample Node application. Through the configuration settings, we'll ensure the environment is load-balanced, with the load balancer situated in a public subnet. This setup allows the load balancer to be the public entry point, directing traffic to our private infrastructure. Although the EC2 instances are in a private subnet, they still need internet access for updates. To accommodate this, we'll associate them with a NAT gateway in the private subnet, allowing only incoming traffic.&lt;/p&gt;

&lt;p&gt;🔥 &lt;strong&gt;Tip&lt;/strong&gt;&lt;br&gt;
Learn more about load balancers &lt;a href="https://www.nginx.com/resources/glossary/load-balancing/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;🔥 &lt;strong&gt;Tip&lt;/strong&gt;&lt;br&gt;
Learn more about NAT gateways and how they work &lt;a href="https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;
  
  
  4.1.2. Creating the subnets
&lt;/h4&gt;

&lt;p&gt;To create our architecture, we need two public subnets for our load balancer. Create two appropriately names public subnets with the method shown in this article. We will also need one private subnet for our application EC2 instances, so create one private subnet.&lt;/p&gt;

&lt;p&gt;Create a NAT gateway and add it to the private subnet.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwaxuvttq0oel76xj0n5z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwaxuvttq0oel76xj0n5z.png" alt=" " width="800" height="509"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  4.1.3. Creating and configuring the environment
&lt;/h4&gt;

&lt;p&gt;Once the subnets are ready to go, navigate to Elastic Beanstalk and launch the environment creation wizard. Choose the environment name and configure the environment:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Choose a sample Node app as the desired platform&lt;/li&gt;
&lt;li&gt;In the networking settings:

&lt;ol&gt;
&lt;li&gt;Choose your VPC&lt;/li&gt;
&lt;li&gt;Choose the desired private subnet&lt;/li&gt;
&lt;li&gt;Choose the appropriate security group&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;In the &lt;em&gt;Instance traffic and scaling&lt;/em&gt;:

&lt;ol&gt;
&lt;li&gt;Choose the &lt;em&gt;environment type&lt;/em&gt; as &lt;em&gt;load balanced&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Set the load balancer as public&lt;/li&gt;
&lt;li&gt;Select the load balancer public subnets created earlier&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Elastic Beanstalk wizard will do the rest. After a successfull launch, the application should be accessible via the EB public URL.&lt;/p&gt;

&lt;p&gt;ℹ️ &lt;strong&gt;Note!&lt;/strong&gt;&lt;br&gt;
The mentioned configuration may take a substantial time to launch (10 minutes or more). Be patient.&lt;/p&gt;
&lt;h4&gt;
  
  
  4.1.4. Backend design visualisation
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ey2gb5akqdra1sx9y9s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ey2gb5akqdra1sx9y9s.png" alt=" " width="800" height="668"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  4.2. Database: Protecting the database with a jump host + security group access rules
&lt;/h3&gt;
&lt;h4&gt;
  
  
  4.2.1. Creating subnets
&lt;/h4&gt;

&lt;p&gt;Firstly, let's create the private subnets for the database. We need at least two. In this case we'll them &lt;em&gt;private-db-subnet-1&lt;/em&gt; and &lt;em&gt;private-db-subnet-2&lt;/em&gt; and assign IPv4 CIDR blocks of $24.24.2.0/24$ and $24.24.3.0/24$.&lt;/p&gt;

&lt;p&gt;🚨 &lt;strong&gt;Warning!&lt;/strong&gt;&lt;br&gt;
Make sure the subnets have different Availability zones.&lt;/p&gt;

&lt;p&gt;Then create the subnet group for the new database instance, consisting of these two subnets.&lt;/p&gt;

&lt;p&gt;We'll need a public instance for our jump host, which we'll cover shortly. Create a public instance following the method shown earlier. Consider naming it appropriately, in this case we'll choose the name &lt;em&gt;public-db-jump-host-subnet-1&lt;/em&gt;.&lt;/p&gt;
&lt;h4&gt;
  
  
  4.2.2. Creating the database instance
&lt;/h4&gt;

&lt;p&gt;Create an RDS instance in your VPC and set the correct subnet group. At this point, the RDS instance will launch but it won't be accessible since it lives in private subnet space. We will make it accessible from the Internet via a jump host.&lt;/p&gt;
&lt;h4&gt;
  
  
  4.2.3. Creating the jump host
&lt;/h4&gt;

&lt;p&gt;ℹ️ &lt;strong&gt;Note!&lt;/strong&gt;&lt;br&gt;
A jump host configuration is not an ideal approach, but it's a great learning example to grasp different traffic rules and the idea of protecting network instances. It is a potential point of vulnerability as it's exposed to the internet. It's crucial to harden its security, apply timely patches, and follow best practices to minimize risks.&lt;/p&gt;

&lt;p&gt;A jump host (or &lt;em&gt;bastion host&lt;/em&gt;) is a special-purpose node (computer, virtual machine) in a computer network configured to withstand attacks and act as a gateway to access resources inside a private network from the external world. &lt;/p&gt;

&lt;p&gt;In this context, we'll utilize the jump host as a bridge to connect to our RDS instance situated in a private subnet.&lt;/p&gt;

&lt;p&gt;We'll configure our jump host as a Linux machine using the EC2 service. We'll launch a simple EC2 instance in the public subnet, exposed to the Internet. By configuring the SSH keys an outside user will be able to securely connect to a public node in our network, from which they'll be able to access protected nodes.&lt;/p&gt;

&lt;p&gt;ℹ️ &lt;strong&gt;Note!&lt;/strong&gt;&lt;br&gt;
Basic knowledge of SSH cryptographic protocol is required. Learn the basics &lt;a href="https://www.geeksforgeeks.org/introduction-to-sshsecure-shell-keys/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's create a Linux machine with EC2. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Choose instance name&lt;/li&gt;
&lt;li&gt;Use &lt;em&gt;Amazon Linux 2023 64-bit&lt;/em&gt; image or newer&lt;/li&gt;
&lt;li&gt;Choose &lt;em&gt;t3.micro&lt;/em&gt; instance type (free tier eligible)&lt;/li&gt;
&lt;li&gt;Create a new key pair for login (by creating a new pair, the browser will prompt you to download the key)&lt;/li&gt;
&lt;li&gt;Configure the network settings

&lt;ol&gt;
&lt;li&gt;Select your VPC&lt;/li&gt;
&lt;li&gt;Select the jump host public subnet as the desired subnet&lt;/li&gt;
&lt;li&gt;Set &lt;em&gt;Auto-assign public IP&lt;/em&gt; to &lt;em&gt;Enable&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Make sure the wizard assigns a new security group tp the instance by selecting the option &lt;em&gt;Create security group&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Make sure the inbound security group rules allow SSH traffic on port 22 from anywhere (more on this later)&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Submit the form&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now the EC2 instance should boot up within a couple of minutes.&lt;/p&gt;
&lt;h4&gt;
  
  
  4.2.4. Connecting to the database
&lt;/h4&gt;

&lt;p&gt;Now our jump host and database should be properly configured for the outside user to gain access via the secure node. To connect to the database the user can SSH into the secure node like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh ec2-user@&amp;lt;MACHINE IP ADDRESS&amp;gt; -i &amp;lt;PATH_TO_PRIVATE_KEY&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with the desired output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   ,     #_
   ~\_  ####_        Amazon Linux 2023
  ~~  \_#####\
  ~~     \###|
  ~~       \#/ ___   https://aws.amazon.com/linux/amazon-linux-2023
   ~~       V~' '-&amp;gt;
    ~~~         /
      ~~._.   _/
         _/ _/
       _/m/'
Last login: Mon Aug 21 12:54:33 2023 from &amp;lt;REMOTE USER IP&amp;gt;
[ec2-user@ip-&amp;lt;VPC PRIVATE NETWORK IP&amp;gt; ~]$ 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This confirms correct configuration of the jump host.&lt;/p&gt;

&lt;p&gt;🔥 &lt;strong&gt;Tip&lt;/strong&gt;&lt;br&gt;
For .pem files used for SSH access, you should set the permissions to be read-only by the owner. This ensures that the private key remains confidential and isn't accidentally modified.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You can set the correct permissions using the `chmod` command:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;```
chmod 400 /path/to/your_key.pem
```
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;To securely access a database on a remote machine without exposing it directly, we can create an SSH tunnel. This technique involves forwarding a local port on your machine to a port on the remote database server, essentially making the database accessible as if it were running locally.&lt;/p&gt;

&lt;p&gt;The command for setting up this SSH tunnel is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssh -L _LOCAL_PORT_:_REMOTE_DATABASE_HOST_:_REMOTE_DATABASE_PORT_ _JUMP_HOST_USERNAME_@_JUMP_HOST_PUBLIC_IP_ -i _PATH_TO_PRIVATE_KEY_

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;LOCAL_PORT&lt;/em&gt;&lt;/strong&gt;: A free port on your local machine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;REMOTE_DATABASE_HOST&lt;/em&gt;&lt;/strong&gt;: The hostname or IP address where the database resides.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;REMOTE_DATABASE_PORT&lt;/em&gt;&lt;/strong&gt;: The port the database listens to.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;JUMP_HOST_USERNAME&lt;/em&gt;&lt;/strong&gt;: Username associated with the jump (or bastion) host.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;JUMP_HOST_PUBLIC_IP&lt;/em&gt;&lt;/strong&gt;: The jump host's public IP address.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;PATH_TO_PRIVATE_KEY&lt;/em&gt;&lt;/strong&gt;: Directory path to the SSH private key for authentication.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After setting up the SSH tunnel, connect to the database using your desired database tool or API as if it's on your local machine. Access it at &lt;code&gt;localhost:_LOCAL_PORT_&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  4.2.5. Configuring traffic rules
&lt;/h4&gt;

&lt;p&gt;We have demonstrated how to protect a private database instance by not exposing it to the Internet directly, but rather provide access via a jump host. This is a huge improvement from the original design but there is still room to improve. We will be specfically focusing on security group rules for the jump host and the database to futher comply with the Principle of least privilege.&lt;/p&gt;

&lt;h5&gt;
  
  
  4.2.5.1. Jump host security group
&lt;/h5&gt;

&lt;p&gt;Let's navigate to EC2, select the jump host, and review its security group.&lt;/p&gt;

&lt;p&gt;So far, the jump host listens only for SSH traffic, which is the desired behavior. The potential security risk is that any user, from anywhere in the world, can attempt to connect to the jump host, denoted by the $0.0.0.0/0$ source rule. While SSH itself is secure, limiting the source addresses can significantly reduce the risk of brute-force attacks. Our current outbound rules allow an attacker to potentially reach other parts of the network.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For inbound rules:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Limit Source: Tighten the inbound rules by allowing only trusted IP addresses, such as your company's VPN, specific employee IP addresses, or other controlled networks. This minimizes the exposure to potential attackers by narrowing down the list of IPs that can initiate a connection.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;For outbound rules:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Limit Destination: Outbound traffic from the jump host should be restricted to the necessary destinations. Specifically, it should be able to communicate only with the private IP address of the database instance and any other essential services. This configuration ensures that even if the jump host is compromised, the attacker can't use it as a platform to target other unrelated resources or systems.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Specify Port: While the jump host primarily serves as a bridge to the database, ensure that it's only allowed to communicate on the specific port your database listens on. This minimizes potential misuse of the jump host.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h5&gt;
  
  
  4.2.5.2. Database instance security group
&lt;/h5&gt;

&lt;p&gt;Let's navigate to RDS, select our database instance, and review its associated security group rules:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For inbound rules:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Limit Source: By default, avoid having a wide-open $0.0.0.0/0 source rule. Instead, only allow inbound traffic from trusted sources. The primary source should be the jump host's private IP, ensuring direct connectivity only through the jump host. Depending on your setup, you might also consider connections from other essential components or services.
Specify Port: Ensure that only the specific port your database is listening on is open. This further reduces potential vulnerabilities.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;For outbound rules:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Limit Destination: Your database instance should have a limited scope for outbound connections. It's best to only allow the necessary communication, which might include connecting to specific services or updates. Restricting the outbound traffic ensures that data can't be unexpectedly exfiltrated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No Wildcard Rules: Avoid using wildcard rules that allow the database to connect to any IP on any port. Remember, you want to ensure that if your database were ever compromised, its potential to do harm is restricted.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  4.3. Final architecture visualisation
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8omgc2jqns1cdh2b5k6q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8omgc2jqns1cdh2b5k6q.png" alt=" " width="800" height="656"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  👏 6. Conclusion
&lt;/h2&gt;

&lt;p&gt;Securing cloud deployments is an intricate task that requires methodical planning and execution. Throughout this guide, we've taken a dive into some foundational steps for improving the security of AWS Elastic Beanstalk and RDS instances. By placing our EB instances in private subnets, harnessing load balancers in publicly accessible spaces, and adding an additional layer of protection to our RDS databases with a jump host, we've made significant strides in fortifying cloud deployments on AWS.&lt;/p&gt;

&lt;p&gt;However, it's essential to understand that this is merely an introductory guide. Real-world production environments often demand a myriad of additional techniques, strategies, and concepts to ensure comprehensive protection such as firewall configurations, intrusion detection systems, monitoring and incident response mechanisms.&lt;/p&gt;

&lt;p&gt;Also check out my website for more &lt;a href="https://valentinkuharic.com/" rel="noopener noreferrer"&gt;here&lt;/a&gt;! Feel free to reach out for more info, suggestions and collaborations.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>security</category>
      <category>devops</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Kamiq - a Typescript, lightweight, Nest-like, batteries-included web framework</title>
      <dc:creator>Valentin Kuharic</dc:creator>
      <pubDate>Thu, 10 Aug 2023 15:42:32 +0000</pubDate>
      <link>https://dev.to/valentinkuharic/i-quit-my-job-and-wrote-a-web-framework-4ifd</link>
      <guid>https://dev.to/valentinkuharic/i-quit-my-job-and-wrote-a-web-framework-4ifd</guid>
      <description>&lt;h2&gt;
  
  
  Table of contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Table of contents&lt;/li&gt;
&lt;li&gt;1. Prelude&lt;/li&gt;
&lt;li&gt;Disclaimer&lt;/li&gt;
&lt;li&gt;2. Enough intro - show me the code.&lt;/li&gt;
&lt;li&gt;2.1. Configuring the server&lt;/li&gt;
&lt;li&gt;2.2. Example&lt;/li&gt;
&lt;li&gt;
2.3. Controllers and routes

&lt;ul&gt;
&lt;li&gt;2.3.1. Controllers&lt;/li&gt;
&lt;li&gt;3.3.2. Routes&lt;/li&gt;
&lt;li&gt;2.3.3. Parameters&lt;/li&gt;
&lt;li&gt;2.3.4. Middlewares&lt;/li&gt;
&lt;li&gt;2.3.5. Gaurds&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

2.4. Error handling

&lt;ul&gt;
&lt;li&gt;2.5. Operations&lt;/li&gt;
&lt;li&gt;2.6. Kamiq errors&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;3. Here's the repo&lt;/li&gt;

&lt;li&gt;4. There is a lot more to do&lt;/li&gt;

&lt;li&gt;5. Outro&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  1. Prelude
&lt;/h2&gt;

&lt;p&gt;On my last job, I was handling a project consisting of a legacy backend + frontend codebase where I was constantly refactoring code - it was either unusable, totally unreadable, or both. To make things even worse, the backend was lacking any structure or goal - it was just code thrown around that somehow managed to work most of the time. In the midst of all the refactoring I found myself slowly adding some architectural elements to the codebase, since it was the only way any new code addition could be maintained later. The codebase didn't even separate the controller logic from service logic!&lt;/p&gt;

&lt;p&gt;With time, things started to take shape, and all my architectural additions helped made the codebase kind of usable. Since moving away from Express wasn't a choice at the time, but numerous new features constantly asked for some new abstractions and design patterns just to keep things organized, I slowly found myself with a backend project that I tailored to my kind of thinking.&lt;/p&gt;

&lt;p&gt;In the meantime, I left that job but all those concepts stuck with me, so as a learning project I decided to wrap them in a standalone package that can be used cleanly and simply. I never wrote a package before, but I thought this would be a short, fun and productive endeavour. Here I am sharing it with the world so we can discuss, learn and figure out what makes a good framework together. With that, I present to you: &lt;strong&gt;Kamiq&lt;/strong&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚠️ Disclaimer
&lt;/h2&gt;

&lt;p&gt;Before you dive in:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In this post I'll be talking about a personal learning project I've been working on. Expect a half-baked but interesting project and a discussion on what makes a fun to use web framework. &lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  2. Enough intro - show me the code.
&lt;/h2&gt;

&lt;p&gt;Short description first:&lt;/p&gt;

&lt;p&gt;Kamiq is a TypeScript framework for building server-side applications with heavy decorator usage. It combines object-oriented and functional programming approaches to achieve it's minimal syntax design. Kamiq is built on top of Express.js and by design offers high interoperability with Express, enabling the user to easily port over their existing Express.js code including routes, middlewares and more.&lt;/p&gt;

&lt;p&gt;I'm not treating this project as something I'd like to push through to being complete or production ready - it's merely a learning project and a discussion on node web frameworks in a codebase format. I'm always open to learning new stuff and one of the best ways to learn is to &lt;strong&gt;reinvent the wheel&lt;/strong&gt;, which is what I'm doing here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;The following script covers the most important parts of the project and doesn't cover more specific features and possibilities. Check out the full README on the Github repository (link at the end).&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Right, &lt;strong&gt;let's get to it.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2.1. Configuring the server
&lt;/h2&gt;

&lt;p&gt;To configure your server, instantiate an object from the Server class. Use the public functions to set your configuration object and any other properties.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;reflect-metadata&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Server&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;kamiq&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DefaultErrorHandler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;DefaultRequestLogger&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;kamiq/middlewares&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SampleController&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./controllers/sampleController&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setPort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8001&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useJsonBodyParser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;SampleController&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useCors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setGlobalRequestLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DefaultRequestLogger&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setGlobalErrorHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DefaultErrorHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2.2. Example
&lt;/h2&gt;

&lt;p&gt;Here's an example of how a controller looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BaseController&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;kamiq&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Middleware&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Res&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;kamiq/decorators&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MySampleMiddleware&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../middlewares/sampleMiddleware.middleware&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MySampleMiddleware2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../middlewares/sampleMiddleware2.middleware&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SampleController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;BaseController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Base path for the following routes.&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Guard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AgencyAuthorizer&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;ignore&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Optional way to ignore a guard (or middleware)&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="c1"&gt;// Guards&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Middleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LogSignInEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// Middlewares&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/siginin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Get controller registeres the route with a GET method and handles errors&lt;/span&gt;
  &lt;span class="nf"&gt;signIn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Req&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Res&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IUserSignIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;userId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;signIn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;AuthService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;signIn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Kamiq operation&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;signIn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AuthorizationError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;signIn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Picked up by global err handling middleware&lt;/span&gt;

    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's brake it down:&lt;/p&gt;

&lt;h2&gt;
  
  
  2.3. Controllers and routes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.3.1. Controllers
&lt;/h3&gt;

&lt;p&gt;Controllers are classes that extend the &lt;code&gt;BaseController&lt;/code&gt; class. In each controller class you provide the &lt;code&gt;path&lt;/code&gt; property - a route prefix for all routes defined in the class.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.3.2. Routes
&lt;/h3&gt;

&lt;p&gt;Each route is a function with the name of your choosing to which a decorator is attached with the HTTP method name: &lt;code&gt;@Get()&lt;/code&gt; for a GET method, &lt;code&gt;@Post()&lt;/code&gt; for POST etc. An HTTP decorator combined with a handler function forms a route. HTTP method decorators take in a string argument that is the route specific suffix. Note that this also supports dynamic routes by adding parameters to the route, as shown above in the example with &lt;code&gt;:userId&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.3.3. Parameters
&lt;/h3&gt;

&lt;p&gt;The route handler itself supports multiple decorators that you can inject to get access to various properties of the request lifecycle. Since Kamiq uses &lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;Express.js&lt;/a&gt; to process HTTP requests, you can inject Express &lt;code&gt;Request&lt;/code&gt; and &lt;code&gt;Response&lt;/code&gt; objects into the hander like shown above with the &lt;code&gt;@Req()&lt;/code&gt; and &lt;code&gt;@Res()&lt;/code&gt; decorators. Also, you have access to &lt;code&gt;@Body&lt;/code&gt;, &lt;code&gt;@Query()&lt;/code&gt;, &lt;code&gt;@Param()&lt;/code&gt;, which extract some specific data from the request as shown above.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.3.4. Middlewares
&lt;/h3&gt;

&lt;p&gt;Kamiq also supports middlewares, which you can attach to routes by using the &lt;code&gt;@Middleware&lt;/code&gt; decorator. Middlewares are classes that extend the &lt;code&gt;KamiqMiddleware&lt;/code&gt; interface, which is very similar to Nest's interface where the &lt;code&gt;use()&lt;/code&gt; function is really just a vanilla Express.js middleware function.&lt;/p&gt;

&lt;p&gt;This also has a nice side-effect where middleware functions can be passed arguments which can alter their behaviour. Consider the middleware as shown:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MySampleMiddleware&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;KamiqMiddleware&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;someValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;someValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;someValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;someValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextFunction&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// Can use someValue to change behavior...&lt;/span&gt;

        &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Route&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Middleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MySampleMiddleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Middleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MySampleMiddleware2&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;createUser&lt;/span&gt;&lt;span class="p"&gt;(@&lt;/span&gt;&lt;span class="nd"&gt;Req&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Res&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// @ts-ignore&lt;/span&gt;

        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user created.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that if a route has multiple middlewares attached, the order of execution is respected.&lt;/p&gt;

&lt;p&gt;Middlewares also accept a second argument, an &lt;code&gt;options&lt;/code&gt; object where you can specify middleware execution instructions like the ability to bypass execution while testing with the &lt;code&gt;ignore&lt;/code&gt; property. &lt;/p&gt;

&lt;h3&gt;
  
  
  2.3.5. Guards
&lt;/h3&gt;

&lt;p&gt;Guards are special type of middlewares that follow the rule of single responsibility by only handlding authorization and authentication logic. They implement an interface similar to the middleware interface but they return a &lt;code&gt;boolean&lt;/code&gt; value, corresponds to a successful or a failed operation, where a successful one means the request proceeds to the next middleware in it's lifecycle and a failure results in an authentication error (or a custom error you can define).&lt;/p&gt;

&lt;h2&gt;
  
  
  2.4. Error handling
&lt;/h2&gt;

&lt;p&gt;Error handling in routes is hidden in how they are registered on server start. When routes are being registered they are wrapped in an &lt;code&gt;requestErrorHandler&lt;/code&gt; middleware which wraps the route handler in a try/catch block. This ensures any error being thrown, by the application or the user, will be caught.&lt;/p&gt;

&lt;p&gt;Catching errors is now taken care of, but we still need to handle them. Kamiq offers a public function you can access on the server object called &lt;code&gt;setGlobalErrorHandler&lt;/code&gt; which takes in a class that implements the &lt;code&gt;KamiqErrorMiddleware&lt;/code&gt; interface. This is a wrapper for an express error middleware that you can pass to the function which will register the middleware and process all caught errors.&lt;br&gt;
Kamiq provides a default &lt;code&gt;defaultErrorHandler&lt;/code&gt; middleware you can use - or of course, you can easily write your own.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;BaseError&lt;/code&gt; class is included in the package that extends the Node's &lt;code&gt;Error&lt;/code&gt;, making it trivial to write your own custom errors. Simply extend the &lt;code&gt;BaseError&lt;/code&gt; class, add your own logic and due to the fact that all route handlers are wrapped in a try/catch block, simply throw your custom error anywhere in the handlers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;ping&lt;/span&gt;&lt;span class="p"&gt;(@&lt;/span&gt;&lt;span class="nd"&gt;Res&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CustomAuthError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my error message!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and Kamiq will handle everything for you.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.5. Operations
&lt;/h3&gt;

&lt;p&gt;Operations are a special function type that aide with inter-layer communication within your codebase. Let's consider a simple backend architecture, consisting of three layers: presentation, service and data-access layer.&lt;/p&gt;

&lt;p&gt;Errors should be handled at the controller level, making communication between the layers troublesome, considering any logic may error. This also raises the question of how to handle user-invoked errors at sub-controller levels.&lt;/p&gt;

&lt;p&gt;Any general function can be an Operation by attaching the &lt;code&gt;Operation()&lt;/code&gt; decorator to it.&lt;/p&gt;

&lt;p&gt;Operation functions are general functions that are wrapped in a try/catch block and have an &lt;code&gt;OperationResult&lt;/code&gt; return type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;OperationResult&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures any &lt;code&gt;Operation&lt;/code&gt; function will return an object with the &lt;code&gt;success&lt;/code&gt; property set to &lt;code&gt;true&lt;/code&gt; if the operation was successful, together with the &lt;code&gt;data&lt;/code&gt; property. In case of failure, &lt;code&gt;success&lt;/code&gt; will be &lt;code&gt;false&lt;/code&gt;, and the &lt;code&gt;error&lt;/code&gt; property will be returned, making it very simple for the receiver of the result to conditionally handle errors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Operation function&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Operation&lt;/span&gt;
  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;myOperationFunction&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;oops!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Operation receiver&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;mockControllerFunction&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;operationResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;MyService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;myOperationFunction&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// handling the result:&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;operationResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// handle error case (throw the error and it will be caught)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;operationResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// continue...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tip: Combine service level functions as Operations with the controller-level error handling to create bulletproof controller-service logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.6. Kamiq errors
&lt;/h3&gt;

&lt;p&gt;Kamiq offers descriptive, prettified framework-level error handling. If you make any configuration or definition errors at the framework level, Kamiq will throw it's custom error to help you resolve the problem. Here's an example of such error being thrown, invoked due to a misconfigured &lt;code&gt;port&lt;/code&gt; variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;InvalidArgumentError: 
   ┌ Kamiq encountered an error! ────────────────────────────────────────────┐
   │                                                                         │
   │                                                                         │
   │   InvalidArgumentError:                                                 │
   │   Port must be a number between 1 and 65535. Provided port is 5236203   │
   │                                                                         │
   │   Suggestion: Please check your server configuration.                   │
   │                                                                         │
   │                                                                         │
   │                                                                         │
   └─────────────────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;there's only a few of such errors as of now, but more checks can be easily added.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Here's the repo
&lt;/h2&gt;

&lt;p&gt;You can visit the repository &lt;a href="https://github.com/Valentin331/Kamiq" rel="noopener noreferrer"&gt;here&lt;/a&gt;, or visit the npm page &lt;a href="https://www.npmjs.com/package/kamiq" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. There is a lot more to do
&lt;/h2&gt;

&lt;p&gt;It ain't much, but it's honest work, right?&lt;/p&gt;

&lt;p&gt;There's a lot of features I'd like to add, and many bugs I'd like to fix. Many important functionalities are missing, such as:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Handling cookies&lt;/li&gt;
&lt;li&gt;Handling content types&lt;/li&gt;
&lt;li&gt;File uploading and management&lt;/li&gt;
&lt;li&gt;Monitoring&lt;/li&gt;
&lt;li&gt;Input validation and sanitization&lt;/li&gt;
&lt;li&gt;Rendering templates&lt;/li&gt;
&lt;li&gt;Sessions&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;and more.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Outro
&lt;/h2&gt;

&lt;p&gt;Thank you for reading this through. I'd like to hear your opinion on this project and can't wait to learn from your ideas and discussions. Check out the repository and feel free to voice your opinions. I know there's plenty wrong I did, but improving it is why I'm sharing this in the first place. Enjoy!&lt;/p&gt;

&lt;p&gt;Cover image by &lt;a href="https://www.pexels.com/@trina-snow-388014/" rel="noopener noreferrer"&gt;Trina Snow&lt;/a&gt; (reinventing the wheel, get it?)&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>framework</category>
      <category>node</category>
      <category>backend</category>
    </item>
    <item>
      <title>Beginner-friendy guide to error handling in TypeScript, Node.js, Express.js API design</title>
      <dc:creator>Valentin Kuharic</dc:creator>
      <pubDate>Tue, 21 Dec 2021 22:10:37 +0000</pubDate>
      <link>https://dev.to/valentinkuharic/beginner-friendy-guide-to-error-handling-in-typescript-nodejs-expressjs-api-design-432i</link>
      <guid>https://dev.to/valentinkuharic/beginner-friendy-guide-to-error-handling-in-typescript-nodejs-expressjs-api-design-432i</guid>
      <description>&lt;h2&gt;
  
  
  1. Introduction to the topic
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1.1. Overview
&lt;/h3&gt;

&lt;p&gt;Error handling is pain. You can get pretty far without handling errors correctly, but the bigger the application, the bigger the problems you’re going to face. To really take your API building to the next level, you should tackle the challenge head-on. Error handling is a broad subject, and it can be done in many ways, depending on the application, technologies and more. It’s one of those things that are easy to understand, but hard to fully grasp.&lt;/p&gt;

&lt;h3&gt;
  
  
  1.2. What we’ll be doing
&lt;/h3&gt;

&lt;p&gt;In this article, we’re going to explain a beginner-friendly way of handling errors in Node.js + Express.js API with TypeScript. We are going to explain what an error is, different types of errors that can crop up and how to handle them in our application. Here are some of the things we’ll be doing in the next chapters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;learning what “error handling” really is and the types of errors that you’ll encounter&lt;/li&gt;
&lt;li&gt;learning about the Node.js &lt;code&gt;Error&lt;/code&gt; object and how can we use it&lt;/li&gt;
&lt;li&gt;learning how to create custom error classes and how they can help us develop better APIs and Node applications&lt;/li&gt;
&lt;li&gt;learning about Express middleware and how to use them to handle our errors&lt;/li&gt;
&lt;li&gt;learning how to structure the error information and present it to the consumer and developer&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1.3. Prerequisites
&lt;/h3&gt;

&lt;p&gt;DISCLAMER! &lt;strong&gt;This article assumes you already know some stuff.&lt;/strong&gt; Even though this is beginner-friendly, here’s what you should know to get the most out of this article:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;working knowledge of Node.js&lt;/li&gt;
&lt;li&gt;working knowledge of Express.js (routes, middleware and such)&lt;/li&gt;
&lt;li&gt;basics of TypeScript (and classes!)&lt;/li&gt;
&lt;li&gt;basics of how an API works and is written using Express.js&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Okay. We can begin.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. What is error handling and why do you need it?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;So what exactly is “error handling” really?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Error handling (or exception handling) is the process of responding to the occurrence of errors (anomalous/unwanted behaviour) during the execution of a program. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why do we need error handling?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because we want to make bug fixing less painful. It also helps us write cleaner code since all error handling code is centralized, instead of handling errors wherever we think they might crop up. In the end - the code is more organized, you repeat yourself less and it reduces development and maintenance time.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Types of errors
&lt;/h2&gt;

&lt;p&gt;There are &lt;strong&gt;two main types&lt;/strong&gt; of errors that we need to differentiate and handle accordingly. &lt;/p&gt;

&lt;h3&gt;
  
  
  3.1. &lt;strong&gt;Operational Errors&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Operational errors represent runtime problems. They are not necessarily “bugs”, but are external circumstances that can disrupt the flow of program execution. Even though they're not errors in your code, these situations can (and inevitably will) happen and they need to be handled. Here are some examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An API request fails for some reason (e.g., the server is down or the rate limit is exceeded)&lt;/li&gt;
&lt;li&gt;A database connection cannot be established&lt;/li&gt;
&lt;li&gt;The user sends invalid input data&lt;/li&gt;
&lt;li&gt;system ran out of memory&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3.2. &lt;strong&gt;Programmer errors&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Programmer errors are the real “bugs” and so, they represent issues in the code itself. As mistakes in the syntax or logic of the program, they can be only resolved by changing the source code. Here are some examples of programmer errors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trying to read a property on an object that is not defined&lt;/li&gt;
&lt;li&gt;passing incorrect parameters in a function&lt;/li&gt;
&lt;li&gt;not catching a rejected promise&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. What is a Node error?
&lt;/h2&gt;

&lt;p&gt;Node.js has a built-in object called &lt;code&gt;Error&lt;/code&gt; that we will use as our base to throw errors. When thrown, it has a set of information that will tell us where the error happened, the type of error and what is the problem. The &lt;a href="https://nodejs.org/en/knowledge/errors/what-is-the-error-object/" rel="noopener noreferrer"&gt;Node.js documentation&lt;/a&gt; has a more in-depth explanation.&lt;/p&gt;

&lt;p&gt;We can create an error like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay, so we gave it a string parameter which will be the error message. But what else does this &lt;code&gt;Error&lt;/code&gt; have? Since we’re using typescript, we can check its definition, which will lead us to a typescript &lt;code&gt;interface&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Name&lt;/code&gt; and &lt;code&gt;message&lt;/code&gt; are self-explanatory, while &lt;code&gt;stack&lt;/code&gt; contains the &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;message&lt;/code&gt; and a string describing the point in the code at which the &lt;code&gt;Error&lt;/code&gt; was instantiated. This stack is actually a series of stack frames (learn more about it &lt;a href="https://www.wikiwand.com/en/Call_stack" rel="noopener noreferrer"&gt;here&lt;/a&gt;). Each frame describes a call site within the code that lead to the error being generated. We can &lt;code&gt;console.log()&lt;/code&gt; the stack,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and see what it can tell us. Here’s an example of an error we get when passing a string as an argument to the &lt;code&gt;JSON.parse()&lt;/code&gt; function (which will fail, since &lt;code&gt;JSON.parse()&lt;/code&gt; only takes in JSON data in a string format):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ch0wazex0x7489t2gca.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ch0wazex0x7489t2gca.png" alt=" " width="800" height="112"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see, this error is of type &lt;em&gt;SyntaxError,&lt;/em&gt; with the message “&lt;em&gt;Unexpected token A in JSON at position 0&lt;/em&gt;”. Underneath, we can see the stack frames. This is valuable information we as a developer can use to debug our code and figure out where the problem is - and fix it.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Writing custom error classes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5.1. Custom error classes
&lt;/h3&gt;

&lt;p&gt;As I mentioned before, we can use the built-in &lt;code&gt;Error&lt;/code&gt; object, as it gives us valuable information.&lt;/p&gt;

&lt;p&gt;However, when writing our API we often need to give our developers and consumers of the API a bit more information, so we can make their (and our) life easier.&lt;/p&gt;

&lt;p&gt;To do that, we can write a class that will extend the &lt;code&gt;Error&lt;/code&gt; class with a bit more data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BaseError&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setPrototypeOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;captureStackTrace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we’re creating a &lt;code&gt;BaseError&lt;/code&gt; class that extends the &lt;code&gt;Error&lt;/code&gt; class. The object takes a &lt;code&gt;statusCode&lt;/code&gt; (HTTP status code we will return to the user) and a &lt;code&gt;message&lt;/code&gt; (error message, just like when creating Node’s built-in &lt;code&gt;Error&lt;/code&gt; object).&lt;/p&gt;

&lt;p&gt;Now we can use the &lt;code&gt;BaseError&lt;/code&gt; instead of Node’s &lt;code&gt;Error&lt;/code&gt; class to add the HTTP status code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Import the class&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BaseError&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../utils/error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;extendedError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BaseError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will use this &lt;code&gt;BaseError&lt;/code&gt; class as our base for all our custom errors.&lt;/p&gt;

&lt;p&gt;Now we can use the &lt;code&gt;BaseError&lt;/code&gt; class to extend it and create all our custom errors. These depend on our application needs. For example, if we’re going to have authentication endpoints in our API, we can extend the &lt;code&gt;BaseError&lt;/code&gt; class and create an &lt;code&gt;AuthenticationError&lt;/code&gt; class like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthenticationError&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;BaseError&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will use the same constructor as our &lt;code&gt;BaseError&lt;/code&gt;, but once we use it in our code it will make reading and debugging code much easier.&lt;/p&gt;

&lt;p&gt;Now that we know how to extend the &lt;code&gt;Error&lt;/code&gt; object, we can go a step further. &lt;/p&gt;

&lt;p&gt;A common error we might need is a “&lt;em&gt;not found&lt;/em&gt;” error. Let’s say we have an endpoint where the user specifies a product ID and we try to fetch it from a database. In case we get no results back for that ID, we want to tell the user that the product was not found.&lt;/p&gt;

&lt;p&gt;Since we’re probably going to use the same logic for more than just Products (for example Users, Carts, Locations), let’s make this error reusable. &lt;/p&gt;

&lt;p&gt;Let’s extend the &lt;code&gt;BaseError&lt;/code&gt; class but now, let’s make the status code default to 404 and put a “property” argument in the constructor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NotFoundError&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;BaseError&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;propertyName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;propertyName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`Property '&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;propertyName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;' not found.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;propertyName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;propertyName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now when using the &lt;code&gt;NotFoundError&lt;/code&gt; class, we can just give it the property name, and the object will construct the full message for us (statusCode will default to 404 as you can see from the code).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This is how we can use the error&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;notFoundError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;NotFoundError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Product&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this is how it looks when it’s thrown:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fria07evpc71zkotnofyw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fria07evpc71zkotnofyw.png" alt=" " width="800" height="120"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we can create different errors that suit our needs. Some of the most common examples for an API would be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ValidationError (errors you can use when handling incoming user data)&lt;/li&gt;
&lt;li&gt;DatabaseError (errors you can use to inform the user that there’s a problem with communicating with the database)&lt;/li&gt;
&lt;li&gt;AuthenticationError (error you can use to signal to the user there’s an authentication error)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5.2. Going a step further
&lt;/h3&gt;

&lt;p&gt;Armed with this knowledge, you can go a step further. Depending on your needs, you can add an &lt;code&gt;errorCode&lt;/code&gt; to the &lt;code&gt;BaseError&lt;/code&gt; class, and then use it in some of your custom error classes to make the errors more readable to the consumer.&lt;/p&gt;

&lt;p&gt;For example, you can use the error codes in the &lt;code&gt;AuthenticationError&lt;/code&gt; to tell the consumer the type of auth error. &lt;code&gt;A01&lt;/code&gt; can mean the user is not verified, while &lt;code&gt;A02&lt;/code&gt; can mean that the reset password link has expired. &lt;/p&gt;

&lt;p&gt;Think about your application’s needs, and try to make it as simple as possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.3. Creating and catching errors in controllers
&lt;/h3&gt;

&lt;p&gt;Now let’s take a look at a sample controller (route function) in Express.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sampleController&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextFunction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;successfull&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s try to use our custom error class &lt;code&gt;NotFoundError&lt;/code&gt;.  Let’s use the next() function to pass our custom error object to the next middleware function that will catch the error and take care of it (don’t worry about it, I’ll explain how to catch errors in a minute).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sampleController&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextFunction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;NotFoundError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Product&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;successfull&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will successfully stop the execution of this function and pass the error to the next middleware function. So, this is it?&lt;/p&gt;

&lt;p&gt;Not quite. We still need to handle errors we don’t handle through our custom errors.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.4. Unhandled mistakes
&lt;/h3&gt;

&lt;p&gt;For example, let’s say you write a piece of code that passes all syntax checks, but will throw an error at runtime. These mistakes can happen, and they will. How do we handle them?&lt;/p&gt;

&lt;p&gt;Let’s say you want to use the &lt;code&gt;JSON.parse()&lt;/code&gt; function. This function takes in JSON data formated as a string, but you give it a random string. Giving this promise-based function a string will cause it to throw an error! If not handled, it will throw an &lt;code&gt;UnhandledPromiseRejectionWarning&lt;/code&gt; error.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkr4h4e8br9eyex4scd6u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkr4h4e8br9eyex4scd6u.png" alt=" " width="800" height="156"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, just wrap your code inside a try/catch block, and pass any errors down the middleware line using &lt;code&gt;next()&lt;/code&gt; (again, I will explain this soon)!&lt;/p&gt;

&lt;p&gt;And this really will work. This is not a bad practice, since all errors resulting from promise-based code will be caught inside the &lt;code&gt;.catch()&lt;/code&gt; block. This has a downside though, and it’s the fact that your controller files will be full of repeated try/catch blocks, and we don’t want to repeat ourselves. Luckily, we do have another ace up our sleeve.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.5. handleAsync wrapper
&lt;/h3&gt;

&lt;p&gt;Since we don’t want to write our try/catch blocks in every controller (route function), we can write a middleware function that does that once, and then apply it on every controller.&lt;/p&gt;

&lt;p&gt;Here’s how it looks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;asyncHandler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextFunction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It may look complicated at first, but it’s just a middleware function that acts as a try/catch block with &lt;code&gt;next(err)&lt;/code&gt; inside the &lt;code&gt;catch()&lt;/code&gt;. Now, we can just wrap it around our controllers and that’s it!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sampleController&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;asyncHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextFunction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;successfull&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;something&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, if the same error is thrown, we won’t get an &lt;code&gt;UnhandledPromiseRejectionWarning&lt;/code&gt;, instead, our error handling code will successfully respond and log the error (once we finish writing it, of course. Here’s how it will look like):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5kzxx0x2r7wmaztijurm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5kzxx0x2r7wmaztijurm.png" alt=" " width="587" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fywqbdh0mmi87a1eu5r77.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fywqbdh0mmi87a1eu5r77.png" alt=" " width="800" height="159"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6. How do I handle errors?
&lt;/h2&gt;

&lt;p&gt;Okay, we learned how to create errors. Now what?&lt;/p&gt;

&lt;p&gt;Now we need to figure out how to actually &lt;em&gt;handle&lt;/em&gt; them.&lt;/p&gt;

&lt;h3&gt;
  
  
  6.1. Express middlewares
&lt;/h3&gt;

&lt;p&gt;An express application is essentially a series of middleware function calls. A middleware function has access to the &lt;code&gt;request&lt;/code&gt; object, the &lt;code&gt;response&lt;/code&gt; object, and the &lt;code&gt;next&lt;/code&gt; middleware function.&lt;/p&gt;

&lt;p&gt;Express with route each incoming request through these middlewares, from the first down the chain, until the response is sent to the client. Each middleware function can either pass the request to the next middleware with the next() function, or it can respond to the client and resolve the request.&lt;/p&gt;

&lt;p&gt;Learn more about Express middleware &lt;a href="https://expressjs.com/en/guide/using-middleware.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  6.2. Catching errors in Express
&lt;/h3&gt;

&lt;p&gt;Express has a special type of middleware function called “Error-handling middleware”. These functions have an extra argument &lt;code&gt;err&lt;/code&gt;. Every time an error is passed in a &lt;code&gt;next()&lt;/code&gt; middleware function, Express skips all middleware functions and goes straight to the error-handling ones.&lt;/p&gt;

&lt;p&gt;Here’s an example on how to write one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;errorMiddleware&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextFunction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Do something with the error&lt;/span&gt;
  &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// pass it to the next function&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6.3. What to do with errors
&lt;/h3&gt;

&lt;p&gt;Now that we know how to catch errors, we have to do something with them. In APIs, there are generally two things you should do: respond to the client and log the error.&lt;/p&gt;

&lt;h4&gt;
  
  
  6.3.1. errorReponse middleware (responding to the client)
&lt;/h4&gt;

&lt;p&gt;Personally, when writing APIs I follow a consistent JSON response structure for successful and failed requests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Success&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;response&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;successfull&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;some message if required&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Failure&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;response&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type of error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/path/on/which/it/happened&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;statusCode&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Message that describes the situation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now we’re going to write a middleware that handles the failure part.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;errorResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextFunction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;customError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;NodeError&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SyntaxError&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;customError&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UnhandledError&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s examine the function. We first create the &lt;code&gt;customError&lt;/code&gt; boolean. We check the &lt;a href="http://error.constructor.name" rel="noopener noreferrer"&gt;&lt;code&gt;error.constructor.name&lt;/code&gt;&lt;/a&gt; property which tells us what type of error we’re dealing with. If &lt;code&gt;error.constructor.name&lt;/code&gt; is &lt;code&gt;NodeError&lt;/code&gt; (or some other error we didn’t personally create), we set the boolean to false, otherwise we set it to true. This way we can handle known and unknown errors differently.&lt;/p&gt;

&lt;p&gt;Next, we can respond to the client. We use the &lt;code&gt;res.status()&lt;/code&gt; function to set the HTTP status code and we use the &lt;code&gt;res.json()&lt;/code&gt; function to send the JSON data to the client. When writing the JSON data, we can use the &lt;code&gt;customError&lt;/code&gt; boolean to set certain properties. For instance, if the &lt;code&gt;customError&lt;/code&gt; boolean is false, we will set the error type to ‘UnhandledError’, telling the user we didn’t anticipate this situation, otherwise, we set it to &lt;code&gt;error.constructor.name&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Since the &lt;code&gt;statusCode&lt;/code&gt; property is only available in our custom error objects, we can just return 500 if it’s not available (meaning it’s an unhandled error).&lt;/p&gt;

&lt;p&gt;In the end, we use the &lt;code&gt;next()&lt;/code&gt; function to pass the error to the next middleware.&lt;/p&gt;

&lt;h4&gt;
  
  
  6.3.2. errorLog middleware (logging the error)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;errorLogging&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextFunction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;customError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;NodeError&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SyntaxError&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ERROR&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Type: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;NodeError&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UnhandledError&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Path: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Status code: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function follows the same logic as the one before, with a small difference. Since this logging is intended for developers of the API, we also log the stack.&lt;/p&gt;

&lt;p&gt;As you can see, this will just &lt;code&gt;console.log()&lt;/code&gt; the error data to the system console. In most production APIs logging is a bit more advanced, logging to a file, or logging to an API. Since this part of the API building is very application-specific, I didn’t want to dive in too much. Now that you have the data, choose what approach works best for your application and implement your version of logging. If you’re deploying to a cloud-based deploying service like AWS, you will be able to download log files by just using the middleware function above (AWS saves all the &lt;code&gt;console.log()&lt;/code&gt;s).&lt;/p&gt;

&lt;h2&gt;
  
  
  7. You can handle errors now.
&lt;/h2&gt;

&lt;p&gt;There you go! That should be enough to get you started with handling errors in a TypeScript + Node.js + Express.js API workflow. Note, there’s a lot of room for improvement here. This approach is not the best, nor the fastest, but is pretty straightforward and most importantly, &lt;strong&gt;forgiving&lt;/strong&gt;, and quick to iterate and improve as your API project progresses and demands more from your skills. These concepts are crucial and easy to get started with, and I hope you’ve enjoyed my article and learned something new.&lt;/p&gt;

&lt;p&gt;Here's a GitHub repository I made so you can get the full picture: (&lt;em&gt;coming soon&lt;/em&gt;) &lt;/p&gt;

&lt;p&gt;Think I could’ve done something better? Is something not clear? Write it down in the comments.&lt;/p&gt;

&lt;p&gt;Anyone else you think would benefit from this? Share it!&lt;/p&gt;

&lt;p&gt;Get in touch: &lt;a href="https://t.me/valentinkuharic" rel="noopener noreferrer"&gt;Telegram&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/valentin-kuharic-4468a81a4/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;, &lt;a href="https://www.valentinkuharic.com/" rel="noopener noreferrer"&gt;Website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you 🙂&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>node</category>
    </item>
  </channel>
</rss>
