Hướng dẫn thử thách
1 / 1
Error Handling in Express Review
## HTTP Response Status Codes
- **Status codes** are short numeric messages that tell the client what happened after a request was made (for example, 200, 404, or 500).
### 1xx — Informational
- **100 Continue** — the server tells the client to send the rest of the request.
- **101 Switching Protocols** — the server is switching protocols (commonly seen with WebSockets).
### 2xx — Success
- **200 OK** — the request succeeded.
- **201 Created** — a new resource was successfully created.
- **204 No Content** — the request succeeded but there is no response body (often used for `DELETE`).
### 3xx — Redirection
- **301 Moved Permanently** — the resource has a new permanent URL.
- **302 Found** — the resource is temporarily at a different URL.
- **304 Not Modified** — the client can use its cached version; nothing has changed.
### 4xx — Client Errors
- **400 Bad Request** — the request is malformed or invalid.
- **401 Unauthorized** — authentication is required.
- **403 Forbidden** — authenticated, but does not have permission.
- **404 Not Found** — the requested resource does not exist.
### 5xx — Server Errors
- **500 Internal Server Error** — a generic server-side failure.
- **502 Bad Gateway** — a proxy received an invalid response from another server.
- **503 Service Unavailable** — the server is temporarily overloaded or down.
### Using Status Codes in Express
- `res.status(400).send("Bad Request")` — sends a 400 with a plain text message.
- `res.status(200).json({ message: "Success" })` — sends a 200 with a JSON body.
- `res.status(500).send("Internal Server Error")` — sends a 500 with a message.
## Error Handling in Express
- **Error-handling middleware** has four parameters: `(err, req, res, next)`. The four-parameter signature is what signals to Express that this is an error handler.
- Place error-handling middleware **at the end** of the middleware stack, after all routes.
```javascript
app.use((err, req, res, next) => {
console.error(err.message);
res.status(500).send("Internal Server Error");
});
```
### Express 4 Async Error Handling
- Async errors are **not automatically caught** in Express 4.
- Wrap async logic in `try/catch` and call `next(err)` to forward the error to the error handler.
```javascript
app.get("/user", async (req, res, next) => {
try {
const user = await getUserFromDatabase();
res.send(user);
} catch (err) {
next(err);
}
});
```
- An `asyncHandler` wrapper avoids repeating `try/catch` in every route:
```javascript
function asyncHandler(fn) {
return function (req, res, next) {
Promise.resolve(fn(req, res, next)).catch(next);
};
}
```
### Express 5 Async Error Handling
- In Express 5, async errors and rejected promises are **automatically forwarded** to the error handler — no manual `next(err)` needed.
### Handling 404 Errors
- Add a catch-all middleware **after routes but before the error handler** to handle unmatched routes:
```javascript
app.use((req, res, next) => {
res.status(404).send("Sorry, that route does not exist.");
});
```
### Error Handling Best Practices
- Always place error-handling middleware last.
- Handle 404s separately from other errors.
- In production, log error details internally — never send stack traces to users.
## Debugging and Logging in Express
- **Built-in debugging**: set the `DEBUG` environment variable to enable Express's built-in debug output.
- `DEBUG=express:* node index.js` — enables all Express debug messages.
- `DEBUG=express:router node index.js` — shows only router-related debug output.
- PowerShell: `$env:DEBUG = "express:*"; node index.js`
- CMD: `set DEBUG=express:* && node index.js`
- **`morgan`**: a popular middleware for logging HTTP requests (method, URL, status code, response time).
```javascript
const morgan = require('morgan');
app.use(morgan('dev'));
```
- **Debugging** traces how Express handles requests and middleware without cluttering production logs.
- **Logging** records what's happening across requests — useful for spotting bugs and understanding traffic.
## Health Checks and Graceful Shutdowns
### Health Checks
- A **health check route** reports whether the app is running correctly.
- Load balancers and orchestrators (for example, Kubernetes, AWS Elastic Beanstalk) ping this route to decide if the service is healthy.
- A **200** response means healthy; no response triggers an automatic restart.
```javascript
app.get('/health', (req, res) => {
res.status(200).send('OK');
});
```
### Graceful Shutdown
- A **graceful shutdown** lets the app finish existing requests before stopping, instead of cutting off connections immediately.
- Listen for the `SIGTERM` signal (sent when the process should terminate) and call `server.close()`:
```javascript
process.on('SIGTERM', () => {
server.close(() => {
console.log('Server closed. Cleaning up...');
});
});
```
- Listen for the `SIGINT` signal (sent when the developer presses <kbd>Ctrl</kbd> + <kbd>C</kbd> during local development) and call the same shutdown logic as `SIGTERM`.
### Marking the App Unhealthy Before Shutdown
- Return a **503** from the health check during shutdown so the load balancer stops routing new traffic to the app.
```javascript
let isShuttingDown = false;
app.get('/health', (req, res) => {
if (isShuttingDown) {
res.status(503).send('Shutting down');
} else {
res.status(200).send('OK');
}
});
process.on('SIGTERM', () => {
isShuttingDown = true;
server.close(() => {
console.log('Graceful shutdown complete');
});
});
```
Nhiệm vụ của bạn
Review the Error Handling in Express topics and concepts.
Vượt qua bài kiểm tra hiện tại để mở khóa bài tiếp theo.
main.sql
UTF-8 • Tab Size: 2Kiểm tra bài:⌘↵