नमस्ते दोस्तों! 🙏
स्वागत है The Easy Master पर!
क्या तुमने कभी सोचा है – Express.js app crash क्यों हो जाता है? Aur errors ko properly kaise handle karein?
Jab app production में जाता है, तो errors आना normal है। लेकिन unhandled errors से app crash हो जाता है – user ko “Internal Server Error” dikhta है।
Express.js error handling Hindi में समझना बहुत जरूरी है क्योंकि:
- Production app mein errors handle karna must है
- User experience – meaningful error messages
- Security – stack traces expose nahi karne chahiye
- Debugging – proper error logging
- Interview mein pakka error handling questions puche jayenge
Aaj kya seekhoge?
| Topic | Kya Seekhega? |
|---|---|
| Error Handling Kya Hai? | Sync vs Async errors |
| Custom Error Class | AppError banayenge |
| Try-Catch | Async error handling |
| Async Handler Wrapper | DRY error handling |
| Custom Error Handler | Centralized error handler |
| Process Errors | Uncaught exceptions |
| Production vs Development | Environment-based errors |
Kya tumhe pata hai?
Express default error handler hai, lekin custom error handler se tum control kar sakte ho ki error kaise dikhe!
तो चलिए शुरू करते हैं – Express.js error handling Hindi सीखने का सफर! 🚀1
Table of Contents
1. Error Handling क्या है? – Introduction
Error handling process hai errors ko gracefully handle karne का – bina app crash kare।
Without Error Handling:
// ❌ No error handling – app crashes!
app.get('/api/users/:id', async (req, res) => {
const user = await db.users.findById(req.params.id);
// If user not found or DB error → app crashes!
res.json(user);
});With Error Handling:
// ✅ With error handling – graceful!
app.get('/api/users/:id', async (req, res, next) => {
try {
const user = await db.users.findById(req.params.id);
if (!user) {
return res.status(404).json({ error: 'User not found' });
}
res.json(user);
} catch (error) {
next(error); // Pass to error handler
}
});
// Error handler middleware
app.use((err, req, res, next) => {
console.error(err);
res.status(500).json({ error: 'Something went wrong!' });
});Express.js error handling Hindi में हम production-ready error handling system बनाएंगे।
2. Types of Errors – Operational vs Programming
Operational Errors (Predictable):
// Operational errors – can handle gracefully
const errors = {
'USER_NOT_FOUND': { status: 404, message: 'User not found' },
'INVALID_INPUT': { status: 400, message: 'Invalid input provided' },
'UNAUTHORIZED': { status: 401, message: 'Not authorized' },
'FORBIDDEN': { status: 403, message: 'Access forbidden' },
'DUPLICATE_EMAIL': { status: 409, message: 'Email already exists' },
'DATABASE_ERROR': { status: 500, message: 'Database connection failed' }
};
// These are expected – send meaningful response to clientProgramming Errors (Bugs):
// Programming errors – bugs in code
// These should be fixed, not handled gracefully
// Example: TypeError, ReferenceError, etc.
// These crash the app – log and restartComparison:
| Feature | Operational Errors | Programming Errors |
|---|---|---|
| Predictable | ✅ Yes | ❌ No |
| Can handle | ✅ Yes | ❌ No (fix code) |
| Examples | DB down, invalid input, not found | TypeError, null reference |
| Response to client | Meaningful error message | 500 Internal Error |
| App restart needed | ❌ No | ✅ Yes |
3. Synchronous Error Handling
Express automatically synchronous errors catch कर लेता है।
Synchronous Errors:
const express = require('express');
const app = express();
// Express automatically catches sync errors
app.get('/api/sync-error', (req, res) => {
// This throws error – Express catches it!
throw new Error('Something went wrong!');
res.json({ message: 'Will never reach here' });
});
// Default error handler will send responseCustom Sync Error Handler:
app.get('/api/users/:id', (req, res, next) => {
const user = users.find(u => u.id === parseInt(req.params.id));
if (!user) {
// Create error and pass to next
const error = new Error('User not found');
error.status = 404;
return next(error);
}
res.json(user);
});4. Asynchronous Error Handling – Try-Catch
Express async errors automatically catch nahi karta – हमें try-catch use karna पड़ता है।
Problem (Without Try-Catch):
// ❌ This will crash the app!
app.get('/api/users/:id', async (req, res) => {
const user = await db.users.findById(req.params.id);
// If this promise rejects → app crashes!
res.json(user);
});Solution (With Try-Catch):
// ✅ Using try-catch
app.get('/api/users/:id', async (req, res, next) => {
try {
const user = await db.users.findById(req.params.id);
if (!user) {
const error = new Error('User not found');
error.status = 404;
return next(error);
}
res.json(user);
} catch (error) {
// Pass error to Express error handler
next(error);
}
});Multiple Async Operations:
app.post('/api/orders', async (req, res, next) => {
try {
const { userId, productId, quantity } = req.body;
// Validate user
const user = await db.users.findById(userId);
if (!user) {
const error = new Error('User not found');
error.status = 404;
return next(error);
}
// Check product
const product = await db.products.findById(productId);
if (!product) {
const error = new Error('Product not found');
error.status = 404;
return next(error);
}
// Check stock
if (product.stock < quantity) {
const error = new Error('Insufficient stock');
error.status = 400;
return next(error);
}
// Create order
const order = await db.orders.create({
userId,
productId,
quantity,
total: product.price * quantity
});
// Update stock
await db.products.updateStock(productId, -quantity);
res.status(201).json(order);
} catch (error) {
next(error);
}
});5. Async Handler Wrapper – DRY Pattern
Har route mein try-catch लिखना repetitive है। Async handler wrapper बनाओ – DRY (Don’t Repeat Yourself) principle follow करो।
Basic Async Handler:
// utils/asyncHandler.js
const asyncHandler = (fn) => {
return (req, res, next) => {
Promise.resolve(fn(req, res, next)).catch(next);
};
};
module.exports = asyncHandler;Using Async Handler:
// routes/users.js
const express = require('express');
const asyncHandler = require('../utils/asyncHandler');
const router = express.Router();
// No more try-catch needed!
router.get('/:id', asyncHandler(async (req, res) => {
const user = await db.users.findById(req.params.id);
if (!user) {
const error = new Error('User not found');
error.status = 404;
throw error;
}
res.json(user);
}));
router.post('/', asyncHandler(async (req, res) => {
const { name, email, password } = req.body;
// Validate input
if (!name || !email || !password) {
const error = new Error('All fields are required');
error.status = 400;
throw error;
}
// Check duplicate email
const existingUser = await db.users.findOne({ email });
if (existingUser) {
const error = new Error('Email already exists');
error.status = 409;
throw error;
}
const newUser = await db.users.create({ name, email, password });
res.status(201).json(newUser);
}));
module.exports = router;Advanced Async Handler with Custom Logic:
// utils/asyncHandler.js
const asyncHandler = (fn, options = {}) => {
return (req, res, next) => {
Promise.resolve(fn(req, res, next))
.catch((err) => {
// Add custom properties
err.route = req.route?.path;
err.method = req.method;
// Log error
if (options.log !== false) {
console.error(`[${err.method}] ${err.route} - ${err.message}`);
}
next(err);
});
};
};
module.exports = asyncHandler;6. Custom Error Class – AppError
AppError class banayenge – sab errors consistent रहेंगे।
AppError Class:
// utils/appError.js
class AppError extends Error {
constructor(message, statusCode) {
super(message);
this.statusCode = statusCode;
this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error';
this.isOperational = true;
// Capture stack trace
Error.captureStackTrace(this, this.constructor);
}
}
module.exports = AppError;Using AppError:
const AppError = require('../utils/appError');
const asyncHandler = require('../utils/asyncHandler');
// User routes
router.get('/:id', asyncHandler(async (req, res) => {
const user = await db.users.findById(req.params.id);
if (!user) {
throw new AppError('User not found', 404);
}
res.json(user);
}));
router.post('/', asyncHandler(async (req, res) => {
const { name, email, password } = req.body;
if (!name || !email || !password) {
throw new AppError('Name, email, and password are required', 400);
}
const existingUser = await db.users.findOne({ email });
if (existingUser) {
throw new AppError('Email already exists', 409);
}
const newUser = await db.users.create({ name, email, password });
res.status(201).json(newUser);
}));
router.delete('/:id', asyncHandler(async (req, res) => {
const user = await db.users.findById(req.params.id);
if (!user) {
throw new AppError('User not found', 404);
}
// Only admin can delete
if (req.user.role !== 'admin' && req.user.id !== user.id) {
throw new AppError('You are not authorized to delete this user', 403);
}
await db.users.delete(req.params.id);
res.status(204).send();
}));AppError with More Features:
// utils/appError.js (enhanced)
class AppError extends Error {
constructor(message, statusCode, details = null) {
super(message);
this.statusCode = statusCode;
this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error';
this.isOperational = true;
this.details = details;
this.timestamp = new Date().toISOString();
Error.captureStackTrace(this, this.constructor);
}
// Static factory methods
static badRequest(message, details) {
return new AppError(message, 400, details);
}
static unauthorized(message = 'Not authorized') {
return new AppError(message, 401);
}
static forbidden(message = 'Access forbidden') {
return new AppError(message, 403);
}
static notFound(message = 'Resource not found') {
return new AppError(message, 404);
}
static conflict(message, details) {
return new AppError(message, 409, details);
}
static internal(message = 'Internal server error') {
return new AppError(message, 500);
}
}
module.exports = AppError;// Usage
if (!user) {
throw AppError.notFound('User not found');
}
if (password.length < 6) {
throw AppError.badRequest('Password too short', {
minLength: 6,
currentLength: password.length
});
}
if (existingEmail) {
throw AppError.conflict('Email already registered');
}7. Custom Error Handler Middleware
Complete Error Handler:
// middleware/errorHandler.js
const AppError = require('../utils/appError');
// Handle specific error types
const handleCastErrorDB = (err) => {
const message = `Invalid ${err.path}: ${err.value}`;
return new AppError(message, 400);
};
const handleDuplicateFieldsDB = (err) => {
const value = err.errmsg.match(/(["'])(\\?.)*?\1/)[0];
const message = `Duplicate field value: ${value}. Please use another value!`;
return new AppError(message, 409);
};
const handleValidationErrorDB = (err) => {
const errors = Object.values(err.errors).map(el => el.message);
const message = `Invalid input data. ${errors.join('. ')}`;
return new AppError(message, 400, errors);
};
const handleJWTError = () => new AppError('Invalid token. Please log in again!', 401);
const handleJWTExpiredError = () => new AppError('Your token has expired! Please log in again.', 401);
// Send error in development
const sendErrorDev = (err, res) => {
res.status(err.statusCode).json({
success: false,
error: err,
message: err.message,
stack: err.stack,
details: err.details
});
};
// Send error in production
const sendErrorProd = (err, res) => {
// Operational, trusted error: send message to client
if (err.isOperational) {
res.status(err.statusCode).json({
success: false,
message: err.message,
...(err.details && { details: err.details })
});
} else {
// Programming or unknown error: don't leak error details
console.error('ERROR 💥', err);
res.status(500).json({
success: false,
message: 'Something went wrong!'
});
}
};
// Main error handler middleware
module.exports = (err, req, res, next) => {
err.statusCode = err.statusCode || 500;
err.status = err.status || 'error';
// Development vs Production
if (process.env.NODE_ENV === 'development') {
sendErrorDev(err, res);
} else {
let error = { ...err };
error.message = err.message;
// Handle specific database errors
if (error.name === 'CastError') error = handleCastErrorDB(error);
if (error.code === 11000) error = handleDuplicateFieldsDB(error);
if (error.name === 'ValidationError') error = handleValidationErrorDB(error);
if (error.name === 'JsonWebTokenError') error = handleJWTError();
if (error.name === 'TokenExpiredError') error = handleJWTExpiredError();
sendErrorProd(error, res);
}
};Using Error Handler:
// server.js
const express = require('express');
const AppError = require('./utils/appError');
const errorHandler = require('./middleware/errorHandler');
const app = express();
// Routes
app.use('/api/users', userRoutes);
app.use('/api/products', productRoutes);
// 404 handler (must be before error handler)
app.all('*', (req, res, next) => {
next(new AppError(`Cannot ${req.method} ${req.originalUrl}`, 404));
});
// Global error handler (must be last)
app.use(errorHandler);
app.listen(3000);8. 404 Error Handler
404 handler not error middleware है – यह normal middleware है।
404 Handler:
// middleware/notFound.js
const AppError = require('../utils/appError');
const notFoundHandler = (req, res, next) => {
const error = new AppError(`Cannot ${req.method} ${req.originalUrl}`, 404);
next(error);
};
module.exports = notFoundHandler;Using 404 Handler:
// server.js
const notFoundHandler = require('./middleware/notFound');
const errorHandler = require('./middleware/errorHandler');
// All routes
app.use('/api/users', userRoutes);
app.use('/api/products', productRoutes);
// 404 handler – after all routes
app.use(notFoundHandler);
// Error handler – after 404 handler
app.use(errorHandler);9. Unhandled Rejections and Exceptions
Production mein unhandled errors ko handle karna बहुत जरूरी है।
Global Unhandled Rejection Handler:
// server.js
// Handle uncaught exceptions (synchronous)
process.on('uncaughtException', (err) => {
console.error('UNCAUGHT EXCEPTION! 💥 Shutting down...');
console.error(err.name, err.message, err.stack);
process.exit(1);
});
// Start server
const server = app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
// Handle unhandled promise rejections (async)
process.on('unhandledRejection', (err) => {
console.error('UNHANDLED REJECTION! 💥 Shutting down...');
console.error(err.name, err.message, err.stack);
server.close(() => {
process.exit(1);
});
});
// Graceful shutdown for SIGTERM
process.on('SIGTERM', () => {
console.log('👋 SIGTERM received. Shutting down gracefully...');
server.close(() => {
console.log('💥 Process terminated!');
});
});10. Production vs Development Error Responses
Environment-based Error Handling:
// config/env.js
const environment = process.env.NODE_ENV || 'development';
const config = {
development: {
sendError: (err, res) => {
res.status(err.statusCode).json({
success: false,
message: err.message,
error: err,
stack: err.stack,
details: err.details
});
}
},
production: {
sendError: (err, res) => {
if (err.isOperational) {
res.status(err.statusCode).json({
success: false,
message: err.message,
...(err.details && { details: err.details })
});
} else {
console.error('ERROR 💥', err);
res.status(500).json({
success: false,
message: 'Something went wrong!'
});
}
}
}
};
module.exports = config[environment];Using Environment Config:
// middleware/errorHandler.js
const envErrorHandler = require('../config/env');
module.exports = (err, req, res, next) => {
err.statusCode = err.statusCode || 500;
envErrorHandler.sendError(err, res);
};11. Real-world Error Handling Setup
Complete Production-Ready Setup:
// server.js
const express = require('express');
const mongoose = require('mongoose');
const AppError = require('./utils/appError');
const errorHandler = require('./middleware/errorHandler');
const notFoundHandler = require('./middleware/notFound');
const app = express();
// ============ MIDDLEWARE ============
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// ============ ROUTES ============
app.use('/api/v1/users', userRoutes);
app.use('/api/v1/products', productRoutes);
app.use('/api/v1/orders', orderRoutes);
// ============ HEALTH CHECK ============
app.get('/health', (req, res) => {
res.status(200).json({
status: 'OK',
timestamp: new Date().toISOString(),
uptime: process.uptime(),
environment: process.env.NODE_ENV
});
});
// ============ 404 HANDLER ============
app.use(notFoundHandler);
// ============ GLOBAL ERROR HANDLER ============
app.use(errorHandler);
// ============ START SERVER ============
const PORT = process.env.PORT || 3000;
// Handle uncaught exceptions
process.on('uncaughtException', (err) => {
console.error('UNCAUGHT EXCEPTION! 💥');
console.error(err.name, err.message);
process.exit(1);
});
const server = app.listen(PORT, () => {
console.log(`🚀 Server running on port ${PORT}`);
console.log(`📝 Environment: ${process.env.NODE_ENV}`);
});
// Handle unhandled rejections
process.on('unhandledRejection', (err) => {
console.error('UNHANDLED REJECTION! 💥');
console.error(err.name, err.message);
server.close(() => {
process.exit(1);
});
});
// Graceful shutdown
process.on('SIGTERM', () => {
console.log('👋 SIGTERM received. Shutting down gracefully...');
server.close(() => {
console.log('💥 Process terminated!');
});
});Error Response Examples:
// Development Error Response
{
"success": false,
"message": "User not found",
"error": {
"statusCode": 404,
"status": "fail",
"isOperational": true,
"message": "User not found"
},
"stack": "Error: User not found\n at ...",
"details": null
}
// Production Error Response (Operational)
{
"success": false,
"message": "User not found"
}
// Production Error Response (Programming)
{
"success": false,
"message": "Something went wrong!"
}12. Common Mistakes + Solutions
Mistake 1: Not passing error to next()
// ❌ Error not passed – app hangs
app.get('/api/users/:id', async (req, res) => {
try {
const user = await db.findUser(req.params.id);
res.json(user);
} catch (error) {
console.log(error); // Just logs, no response!
}
});
// ✅ Pass error to next()
app.get('/api/users/:id', async (req, res, next) => {
try {
const user = await db.findUser(req.params.id);
res.json(user);
} catch (error) {
next(error);
}
});Mistake 2: Sending response after error
// ❌ Sending multiple responses
app.get('/api/users/:id', (req, res, next) => {
const user = users.find(u => u.id === parseInt(req.params.id));
if (!user) {
res.status(404).json({ error: 'Not found' });
next(new Error('User not found')); // Still sends error response!
}
res.json(user);
});
// ✅ Either send response OR call next()
app.get('/api/users/:id', (req, res, next) => {
const user = users.find(u => u.id === parseInt(req.params.id));
if (!user) {
return next(new AppError('User not found', 404));
}
res.json(user);
});Mistake 3: Error handler not last
// ❌ Error handler before routes
app.use(errorHandler);
app.use('/api/users', userRoutes); // Routes won't work properly!
// ✅ Error handler LAST
app.use('/api/users', userRoutes);
app.use(errorHandler);Mistake 4: Not handling async errors
// ❌ No error handling for async route
app.get('/api/users/:id', async (req, res) => {
const user = await db.findUser(req.params.id); // Can crash!
res.json(user);
});
// ✅ Use asyncHandler
app.get('/api/users/:id', asyncHandler(async (req, res) => {
const user = await db.findUser(req.params.id);
res.json(user);
}));13. Quick Cheat Sheet
Error Handling Patterns:
| Pattern | Code |
|---|---|
| Sync error | throw new Error('message') |
| Async error | next(error) |
| Custom error | new AppError(message, statusCode) |
| Async handler | asyncHandler(fn) |
| 404 handler | app.use('*', handler) |
| Error handler | app.use((err, req, res, next) => {}) |
Error Handler Order:
// 1. Routes
app.use('/api', routes);
// 2. 404 handler (after routes)
app.use('*', notFoundHandler);
// 3. Error handler (LAST)
app.use(errorHandler);AppError Usage:
// Basic
throw new AppError('User not found', 404);
// With details
throw new AppError('Validation failed', 400, details);
// Static methods
throw AppError.notFound();
throw AppError.badRequest('Invalid email');
throw AppError.unauthorized();
throw AppError.conflict('Email exists');14. FAQ
Q1: Express.js error handling Hindi में सबसे important concept kya hai?next(error) – async errors को error handler तक पहुंचाने का तरीका।
Q2: Sync vs async errors – kya antar hai?
Sync errors Express automatically catch कर लेता है। Async errors को next(error) से pass karna padta है।
Q3: Error handler middleware में 4 parameters kyun?
Express 4 parameters वाले middleware को error handler के रूप में identify करता है।
Q4: 404 handler error handler क्यों नहीं है?
404 handler normal middleware है – यह error नहीं है, sirf “not found” response भेजता है।
Q5: asyncHandler wrapper kyun use karein?
Har route mein try-catch लिखने से बचने के लिए – DRY principle।
Q6: Operational vs Programming errors – kya antar hai?
Operational – predictable, handle कर सकते हो। Programming – bugs, code fix करना पड़ता है।
Q7: Production mein stack trace kyun nahi dikhana chahiye?
Security risk – attackers को app की internal details leak हो सकती हैं।
Q8: unhandledRejection aur uncaughtException mein kya antar hai?unhandledRejection – async promise rejections। uncaughtException – sync errors।
Q9: AppError class kyun banayein?
Consistent error format, operational flag, aur static factory methods के लिए।
Q10: Error handler last mein kyun lagana chahiye?
Taki सभी routes और middleware ke errors catch हो सकें।
15. Conclusion
बहुत बढ़िया दोस्तों! आज हमने Express.js error handling Hindi को पूरी detail में समझा।
Quick Recap:
| Concept | Key Takeaway |
|---|---|
| Sync Errors | Express automatically catches |
| Async Errors | Use next(error) or asyncHandler |
| AppError Class | Custom error with status code |
| Error Handler | 4 parameters, must be LAST |
| 404 Handler | Normal middleware, before error handler |
| Production | Hide stack traces |
Mera personal experience:
Error handling samajhne ke baad meri APIs production-ready ho gayi। Pehले errors se app crash ho jata था, ab gracefully handle हो जाता है। Custom error handler se debugging भी easy हो गई।
Tum bhi ye steps follow karo:
- ✅ AppError class banao
- ✅ asyncHandler wrapper banao
- ✅ Custom error handler middleware banao
- ✅ 404 handler add karo
- ✅ Unhandled rejection/exception handle karo
अब तुम्हारी बारी है!
नीचे comment में बताओ:
- तुमने कभी production mein error handling implement kiya है?
- तुम्हें कौन सा error type sabse ज्यादा face karta है?
- अगला topic क्या चाहिए? (MongoDB with Mongoose? JWT Authentication? File Upload?)
The Easy Master पर बने रहो। Happy Error Handling! 🚀🔧
Resources
Additional Resources
- React.js Kya Hai? JSX aur Components Samjhe – Beginner Guide 2026
- React Props and State Data Flow Hindi – समझे आसान भाषा में 2026
- React Router v6 – Multi-Page App Banaye (Routing Guide) 2026
- Advanced React Hooks – useContext and useReducer Samjhe 2026
- Redux Toolkit Simplified – State Management Aasaan Tarika 2026
- React API Integration Made Easy with Fetch and Axios
- React Performance Optimization – App Ko Fast कैसे बनाएं 2026
- React 19 New Features – AI Integration with React (2026)
- Node.js क्या है? 2026 में अपना पहला Backend Server बनाएँ
- NPM Packages कैसे इंस्टॉल करें? Modules (ESM vs CommonJS) 2026
- Express.js Tutorial – REST API Routing और Middleware समझे 2026
- Prisma ORM MongoDB से Database Connect कैसे करें – Easy Tutorial Hindi
- JWT Authentication Node.js – Secure Login System बनाए 2026
- WebSockets Node.js – Live Chat App कैसे बनाएं (Socket.io)
- Async Await vs Promises – Node.js में Async Code कैसे सीखें?
- Microservices Architecture node.js आसान हिंदी Explanation 2026
- Docker से Node.js App Production Ready Deploy करें 2026
- Express.js Setup – पहला Server कैसे बनाएं (Step-by-Step) 2026
- Express.js Routing – GET POST PUT DELETE Complete Guide
- Express Middleware समझे – Application, Router, Error Middleware