DEV Community

Precious Afolabi
Precious Afolabi

Posted on

Week 12: Express.js and Refactoring Error Handling

Express.js and Better Error Handling
Week 12 covered Express.js fundamentals and refactoring my blog platform with proper error handling patterns.

Express.js Fundamentals

Middleware
Middleware is how Express processes requests. Functions that run before your route handlers. Each middleware can modify the request, send a response, or pass control to the next middleware.

Built-in middleware parses JSON bodies and URL-encoded data. Custom middleware handles logging, authentication, and timing. The order matters. Middleware runs in the order you define it.

Understanding middleware flow changed how I structure applications. Instead of handling everything in route handlers, break concerns into separate middleware functions.

Routing and Controllers
Express routing maps URLs to handlers. Instead of one massive file, separate routes into logical groups. User routes, post routes, comment routes.
Controllers handle the business logic. Route files define endpoints, and controllers implement what happens when those endpoints are hit—clean separation of concerns.

Validation
Input validation with express-validator. Define validation rules, check for errors, and return appropriate responses. Users send all kinds of invalid data. Validation catches it before it reaches your database.

Centralized Error Handling
This was the game changer. Instead of repeating try/catch blocks in every async function, use two utilities.

AppError Class
Custom error class that includes status code and message. Throw this instead of generic errors.
When something goes wrong, throw an AppError with the appropriate status code. The centralized error handler catches it and sends the right response.

catchAsync Wrapper
Wraps async route handlers. Automatically catches errors and forwards them to the error-handling middleware. No more try/catch in every function.
Before catchAsync, every async controller had repetitive error handling. After catchAsync, the code is clean, and errors are handled consistently.

Global Error Handler
One middleware at the end catches all errors. Whether you threw an AppError or something unexpected happened, it handles the response.
Errors get logged, appropriate status codes get sent, and users get meaningful error messages instead of crashes.

Refactoring My Blog Platform
Applied these patterns to my existing blog platform project.

What Changed
Added AppError and catchAsync throughout all controllers. Removed repetitive try/catch blocks. Errors now flow to one central handler instead of being handled inconsistently everywhere.

Implemented a comments API. Users can create comments on blog posts and delete their own comments. Full CRUD operations with proper error handling, validation, and authentication middleware.

The Challenge
Understanding how error handling actually works was tricky. How errors propagate in async functions, when to throw versus when to pass to next, how the global error handler receives them.
The pattern clicked after refactoring existing code. Seeing all the repetition disappear made the value clear.

The Result
Cleaner controllers. Consistent error responses. One place to modify error handling instead of updating dozens of try/catch blocks. Adding new features is faster because the error handling is already solved.

Key Lessons
Middleware order matters. Authentication before validation before handlers.
Centralized error handling removes boilerplate and ensures consistency.
AppError and catchAsync are simple patterns that make code significantly cleaner.
Validation prevents bad data from reaching your database.
Error handling isn't optional. Things break in production.

Moving Forward
Starting databases. Learning MongoDB and PostgreSQL fundamentals. Understanding both NoSQL and relational databases.

Project Links
GitHub: https://github.com/Precixphantom/blog-platform
Live Demo: https://blog-platform-6wv2.onrender.com

Question: How do you handle errors in your backend applications?

Top comments (0)