Error Handling
Relevant source files
The following files were used as context for generating this wiki page:The LostData project employs two distinct error handling strategies tailored to its different components. The primary strategy, within the Node.js/Express backend, uses a consistent pattern of try...catch blocks within async API route handlers. This approach captures exceptions during database operations or other processing and returns structured JSON error messages with appropriate HTTP status codes. This ensures that the client-side application receives clear feedback on failed requests.
A secondary, simpler error handling mechanism is present in the standalone Python utility script (model_database.py). This script handles errors by checking for the existence of data before performing operations and printing informative messages directly to the console. This is suitable for its role as a command-line tool for data management.
Server-Side Error Handling (Node.js)
Error handling in the main Express server is implemented at the route handler level. It focuses on capturing exceptions, particularly from database interactions, and responding with standardized HTTP status codes and JSON error objects.
Sources: server.js, APP/models/model.model.js
API Endpoint Error Strategy
All asynchronous API route handlers for CRUD operations on models are wrapped in a try...catch block. If an operation within the try block fails (e.g., a database query error or a validation error from the Mongoose schema), the catch block is executed. It sends an HTTP 500 Internal Server Error response containing a JSON object with the error message.
This diagram illustrates the sequence of events when a database error occurs during an API call.
Sources: server.js:61-67
The following code snippet shows the typical implementation for an API endpoint.
// server.js:77-85
app.put("/api/models/:id", isAdmin, async (req, res) => {
try {
const model = await Model.findById(req.params.id);
model.history.push({ timestamp: new Date(), action: 'update', user: req.session.user.email, changes: Object.keys(req.body) });
Object.assign(model, req.body);
await model.save();
res.json(model);
} catch (err) {
res.status(500).json({ error: err.message });
}
});
Sources: server.js:77-85, APP/models/model.model.js (Mongoose save() can throw validation errors defined in the schema)
Common HTTP Error Responses
The server utilizes specific HTTP status codes to indicate the nature of an error to the client.
| Status Code | Response Body | Context | Source File |
|---|---|---|---|
500 | { "error": err.message } | A generic server-side error occurred, typically from a failed database operation in a try...catch block. | server.js |
403 | { "message": "Admin required" } | A non-admin user attempted to access an admin-only route. | server.js:47 |
500 | {...err} | An error occurred during the bulk insertion of records from an imported CSV file. | server.js:126 |
Authorization Errors
Access to protected routes (e.g., creating, updating, or deleting models) is controlled by the isAdmin middleware. If a user without admin privileges attempts to access one of these routes, the middleware immediately ends the request-response cycle by sending an HTTP 403 Forbidden status and a JSON message, preventing the route handler from executing.
This flowchart shows the logic of the isAdmin middleware.
Sources: server.js:45-48
// server.js:45-48
const isAdmin = (req, res, next) => {
if (req.session.user && req.session.user.role === 'admin') next();
else res.status(403).json({ message: 'Admin required' });
};
Sources: server.js:45-48
Database Connection and Seeding Errors
Errors during the initial database connection are handled using promise-based .catch() blocks. In both the main server and the seeding script, a failed connection attempt results in the error being logged to the console. This will typically prevent the application or script from starting correctly.
// In server.js
db.mongoose.connect(process.env.MONGODB_URI).then(() => console.log("DB connected")).catch(err => console.log(err));
// In seed.js
db.mongoose.connect(db.url)
.then(() => {
// ... seeding logic
})
.catch(err => console.log(err));
Sources: server.js:25, seed.js:100-107, APP/config/db.config.js
Similarly, if an error occurs while inserting the seed data, it is caught and logged to the console, and the script process is not terminated successfully.
// seed.js:103-106
Model.insertMany(modelsData)
.then(() => {
console.log("Models seeded!");
process.exit(0);
})
.catch(err => console.log(err));
Sources: seed.js:103-106
Python Script Error Handling
The model_database.py script, a command-line utility for managing a local JSON database of models, uses a different, more direct error handling approach. Instead of try...except blocks for most operations, it performs conditional checks to validate user input before proceeding. Errors are reported by printing formatted strings to the console.
Sources: model_database.py
For example, when removing or viewing a model, the script first checks if the model name exists as a key in its self.models dictionary. If the model is not found, it prints an error message and takes no further action.
This flowchart illustrates the error handling logic for removing a model.
Sources: model_database.py:38-44
The implementation below shows this direct, console-based feedback mechanism.
# model_database.py:38-44
def remove_model(self, name):
"""Remove a model by name."""
if name in self.models:
del self.models[name]
self.save_data()
print(f"🗑️ Removed model: {name}")
else:
print(f"❌ Model '{name}' not found.")
Sources: model_database.py:38-44
Summary
The LostData project demonstrates two context-appropriate error handling paradigms. The Node.js web server provides robust, client-facing error responses via HTTP, which is essential for a web application architecture. This allows the frontend to react to failures gracefully. In contrast, the Python utility script uses a simpler, console-based feedback mechanism that is perfectly suited for its role as an interactive command-line tool. Both systems ensure that failures are handled and reported, preventing unexpected crashes and providing useful feedback to the user or developer.