75 phút
Middleware Nâng cao và Error Handling
Custom Middleware
Logging Middleware
const logger = (req, res, next) => {
console.log(`${new Date().toISOString()} - ${req.method} ${req.url}`);
next();
};
app.use(logger);
Authentication Middleware
const authenticate = (req, res, next) => {
const token = req.headers.authorization?.replace('Bearer ', '');
if (!token) {
return res.status(401).json({ error: 'No token provided' });
}
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = decoded;
next();
} catch (error) {
return res.status(401).json({ error: 'Invalid token' });
}
};
app.get('/profile', authenticate, (req, res) => {
res.json({ user: req.user });
});
Error Handling Middleware
Custom Error Class
class AppError extends Error {
constructor(message, statusCode) {
super(message);
this.statusCode = statusCode;
this.isOperational = true;
Error.captureStackTrace(this, this.constructor);
}
}
Global Error Handler
const errorHandler = (err, req, res, next) => {
err.statusCode = err.statusCode || 500;
err.status = err.status || 'error';
if (process.env.NODE_ENV === 'development') {
res.status(err.statusCode).json({
status: err.status,
error: err,
message: err.message,
stack: err.stack
});
} else {
// Production
if (err.isOperational) {
res.status(err.statusCode).json({
status: err.status,
message: err.message
});
} else {
console.error('ERROR 💥', err);
res.status(500).json({
status: 'error',
message: 'Something went wrong!'
});
}
}
};
app.use(errorHandler);
Async Error Handling
Async Wrapper
const asyncHandler = (fn) => (req, res, next) => {
Promise.resolve(fn(req, res, next)).catch(next);
};
// Usage
app.get('/users', asyncHandler(async (req, res) => {
const users = await User.find();
res.json(users);
}));
Bài tập thực hành
Hãy triển khai error handling cho REST API!