Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 121 additions & 1 deletion absolute-beginners/full-stack/backend/error-handling.mdx
Original file line number Diff line number Diff line change
@@ -1 +1,121 @@
<ComingSoon />
---
title: "Error Handling in Express"
sidebar_label: "5. Error Handling"
sidebar_position: 5
description: "Learn how to catch and handle errors in your Node.js and Express applications to prevent crashes."
tags: ["Error Handling", "Express.js", "Node.js", "Backend Development"]
keywords: ["Error Handling", "Express.js", "Node.js", "Try...Catch", "Error Middleware", "Custom Errors", "404 Handling"]
---

In a basic script, if an error happens, the program stops. In a backend server, if the program stops, your entire website goes offline for everyone! Error handling is the art of catching those "oops" moments and responding gracefully.

## 1. The Try...Catch Block

The most basic way to handle errors in JavaScript is the `try...catch` block. You "try" to run some code, and if it fails, the "catch" block takes over.

```javascript title="server.js"
app.get('/api/data', async (req, res) => {
try {
const data = await someDatabaseCall();
res.json(data);
} catch (error) {
console.error(error); // Log it for the developer
res.status(500).send("Something went wrong on our end!");
}
});
```

## 2. Express Error Middleware

Express has a special type of middleware specifically for errors. While normal middleware has three arguments `(req, res, next)`, error middleware has **four**: `(err, req, res, next)`.

If you place this at the very bottom of your `server.js` (after all your routes), it will catch every error that happens in your app.

```javascript title="server.js"
// Universal Error Handler
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({
success: false,
message: "Internal Server Error",
error: err.message // Optional: only show in development
});
Comment on lines +38 to +42
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

Exposing the error message directly to the client can leak sensitive information about the server's internal state. It is safer to only include detailed error information when the application is running in a development environment.

  res.status(500).json({
    success: false,
    message: "Internal Server Error",
    error: process.env.NODE_ENV === 'development' ? err.message : {}
  });

});
```

## 3. Throwing Custom Errors

Sometimes, the code isn't "broken," but the user did something wrong (like entering the wrong password). In these cases, you can "throw" your own error to trigger the catch block.

```javascript title="server.js"
app.post('/login', (req, res, next) => {
const { password } = req.body;

if (password !== "12345") {
const error = new Error("Wrong Password!");
error.status = 401;
return next(error); // Passes the error to the error middleware
}

res.send("Logged in!");
});
```

## 4. Handling 404 (Not Found)

What happens if a user visits a URL that doesn't exist? By default, Express sends a plain text message. At the Hub, we prefer to send a clean JSON response or a custom 404 page.

**Add this right before your error middleware:**

```javascript title="server.js"
app.use((req, res) => {
res.status(404).json({ message: "Requested resource not found" });
});
```

## 5. Best Practices for Error Messages

When an error occurs, you must be careful about what you tell the user:

| Scenario | Good Response | Bad Response |
| :--- | :--- | :--- |
| **Database Failed** | "Service temporarily unavailable." | "Error: Cannot connect to MongoDB at 192.168..." |
| **Wrong Input** | "Please enter a valid email." | "Internal logic failed at line 42." |
| **Security** | "Invalid credentials." | "That email exists, but the password is wrong." |

:::tip
Never reveal your database structure or file paths in an error message. It gives hackers a map of your server!
:::

## Practice: The "Safe Divider"

Build a route `/divide/:a/:b` that:
1. Takes two numbers from the URL.
2. Divides `a` by `b`.
3. **Error Check:** If `b` is `0`, throw an error (you can't divide by zero!).
4. **Error Check:** If `a` or `b` are not numbers, throw an error.

```javascript title="server.js"
app.get('/divide/:a/:b', (req, res, next) => {
const a = parseFloat(req.params.a);
const b = parseFloat(req.params.b);

if (isNaN(a) || isNaN(b)) {
const error = new Error("Both parameters must be numbers.");
error.status = 400;
return next(error);
}

if (b === 0) {
const error = new Error("Cannot divide by zero.");
error.status = 400;
return next(error);
}

res.json({ result: a / b });
});
```

:::info Async Wrapper
In modern Express, catching errors in `async` functions can be repetitive. Many developers use a "Catch-Async" helper function or a library like `express-async-errors` to automatically catch errors and send them to the global error handler.
:::
119 changes: 118 additions & 1 deletion absolute-beginners/full-stack/backend/express.mdx
Original file line number Diff line number Diff line change
@@ -1 +1,118 @@
<ComingSoon />
---
title: "Express.js Framework"
sidebar_label: "3. Express.js"
sidebar_position: 3
description: "Learn how to build a web server quickly using Express.js, the most popular Node.js framework. Understand routing, middleware, and how to handle requests and responses. Get hands-on experience creating your first API endpoints."
tags: ["Express.js", "Backend", "Node.js", "Web Server", "API"]
keywords: ["Express.js", "Web Framework", "Routing", "Middleware", "API Endpoints", "Node.js"]
---

If Node.js is the "Environment," then **Express.js** is the "Framework." It is designed to make building web applications and APIs much easier and faster. At **CodeHarborHub**, we use Express because it is the industry standard for JavaScript backends.

## 1. Why use Express?

Building a server using only built-in Node.js `http` module is like building a house by making your own bricks. Express gives you the bricks already made:
* **Easy Routing:** Define what happens when a user visits `/home` vs `/profile`.
* **Middleware Support:** Add extra features like logging or security with one line of code.
* **JSON Friendly:** Perfect for talking to React frontends.

## 2. Setting Up Express

First, create a folder for your project, initialize it, and install Express:

```bash
mkdir my-server
cd my-server
npm init -y
npm install express
```

## 3. The "Hello World" Server

Create a file named `server.js` and add this code. This is the simplest Express server possible:

```javascript title="server.js"
const express = require('express');
const app = express();
const PORT = 3000;

// This is a "Route"
app.get('/', (req, res) => {
res.send('Welcome to the CodeHarborHub Server!');
});

app.listen(PORT, () => {
console.log(`Server is running at http://localhost:${PORT}`);
});
```

To start it, run `node server.js` in your terminal. Open your browser and go to `http://localhost:3000`.

## 4. Understanding Request and Response

Every route handler in Express gives you two important objects:

1. **`req` (Request):** Information coming *from* the user (e.g., what they typed in a search bar).
2. **`res` (Response):** What the server sends *back* to the user (e.g., text, HTML, or an image).

## 5. Handling Routes (The Roadmap)

A "Route" is a combination of a **URL** and an **HTTP Method**. The most common methods are:
* **GET:** To "Get" data (e.g., reading a blog post).
* **POST:** To "Send" data (e.g., creating a new user account).
* **PUT:** To "Update" data (e.g., changing your profile picture).
* **DELETE:** To "Remove" data.

```javascript title="server.js"
const express = require('express');
const app = express();
app.use(express.json());

app.get('/api/cricket', (req, res) => {
res.json({ player: "MS Dhoni", shot: "Helicopter Shot" });
});

app.post('/api/login', (req, res) => {
res.send("Processing login...");
});
```

## 6. Nodemon: The Developer's Best Friend

Normally, every time you change your code, you have to stop and restart the server manually. **Nodemon** does this for you automatically!

**Install it:**

```bash
npm install -g nodemon
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Installing packages globally with -g is generally discouraged for project-specific tools. It is better to install nodemon as a development dependency to ensure that all developers working on the project use the same version.

npm install --save-dev nodemon

```

**Run your server with it:**

```bash
nodemon server.js
```

## Practice: The Dynamic Greeter

Let's use **URL Parameters** to greet users by name!

```javascript title="server.js"
const express = require('express');
const app = express();

app.get('/greet/:name', (req, res) => {
const userName = req.params.name;
res.send(`Hello ${userName}, welcome to the backend!`);
});
```

*If you visit `http://localhost:3000/greet/Ajay`, the page will say "Hello Ajay, welcome to the backend!"*

:::info Middleware
Middleware functions are functions that have access to the request and response objects. They run *before* your route handler. A very common one is `express.json()`, which allows your server to read JSON data sent from the frontend.

```javascript title="server.js"
app.use(express.json());
```
:::
118 changes: 117 additions & 1 deletion absolute-beginners/full-stack/backend/middleware.mdx
Original file line number Diff line number Diff line change
@@ -1 +1,117 @@
<ComingSoon />
---
title: "Understanding Middleware in Express"
sidebar_label: "6. Middleware"
sidebar_position: 6
description: "Learn how to use and create middleware to process requests before they reach your routes."
tags: ["Middleware", "Express.js", "Node.js", "Backend Development"]
keywords: ["Middleware", "Express.js", "Node.js", "Custom Middleware", "Built-in Middleware", "Third-Party Middleware", "next() Function"]
---

In Express, **Middleware** is a function that runs **after** the incoming request is received and **before** the final response is sent. It has access to the Request (`req`), Response (`res`), and the next function in the cycle.

## 1. How Middleware Works

Think of Middleware as a series of checkpoints. Each middleware can:
1. Execute any code.
2. Make changes to the `req` and `res` objects.
3. End the request-response cycle (e.g., if a user isn't logged in).
4. Call the **`next()`** function to pass control to the next middleware.

```javascript title="server.js"
app.use((req, res, next) => {
console.log("This runs for every request!");
next(); // Passes control to the next middleware or route handler
});
```

## 2. Types of Middleware

### 1. Built-in Middleware
Express comes with some tools already included. The most common one is `express.json()`, which helps your server understand JSON data sent by a frontend (like a React app).

```javascript title="server.js"
app.use(express.json()); // Essential for modern apps!
```

### 2. Third-Party Middleware
The community has built amazing tools that you can install via NPM.
* **Morgan:** Logs every request so you can see who is visiting your site.
* **Cors:** Allows your frontend to talk to your backend safely.
* **Dotenv:** Helps manage "secret" environment variables.

```bash
npm install morgan
```

Now, let's use it in our `server.js`:

```javascript title="server.js"
const morgan = require('morgan');
app.use(morgan('dev')); // Now every request shows up in your terminal!
```

### 3. Custom Middleware
You can write your own middleware to do anything you want! This is great for things like checking if a user is an admin or logging the time of a request.

## 3. Building Your First Custom Middleware

Let's create a "Logger" that prints the URL and the current time whenever someone visits our site.

```javascript title="server.js"
const myLogger = (req, res, next) => {
const currentTime = new Date().toLocaleTimeString();
console.log(`[${currentTime}] Request made to: ${req.url}`);

// CRITICAL: You must call next() or the browser will hang forever!
next();
};

// Apply it to the whole app
app.use(myLogger);
```

## 4. Global vs. Specific Middleware

At **CodeHarborHub**, we teach you to be precise with your code. You don't always want middleware to run on *every* page.

### Global Middleware

Runs for every single route in your app.

```javascript title="server.js"
app.use(express.json());
```

### Specific Middleware

Only runs for a specific route. This is perfect for "Protected Routes" (e.g., only users who are logged in can see `/dashboard`).

```javascript title="server.js"
const checkAuth = (req, res, next) => {
const isAuthorized = true; // In real life, check for a token
if (isAuthorized) {
next();
} else {
res.status(401).send("Access Denied!");
}
};

app.get('/dashboard', checkAuth, (req, res) => {
res.send("Welcome to your secret dashboard!");
});
```

## 5. The Importance of `next()`

If you forget to call `next()`, your request will get "stuck" in that middleware. The user's browser will show a spinning loading icon until it eventually times out. Always remember: **Middleware is a relay race—you must pass the baton!**

## Practice: The "Maintenance Mode" Challenge

Try to create a middleware that prevents anyone from visiting your site.
1. Create a middleware function.
2. Instead of calling `next()`, it should send a message: `"Site under maintenance. Check back later!"`.
3. Apply it to your app and try to visit any route.

:::info Order Matters!
Express runs middleware in the order you write them in your code. If you put your error-handling middleware at the top, it won't catch any errors from the routes below it. Always place global middleware and routes first, and error handlers last.
:::
Loading
Loading