UNPKG

ultimate-crud

Version:

Ultimate dynamic CRUD API generator with REST, GraphQL, OpenAPI support and association handling for Node.js/Express/Sequelize

191 lines (164 loc) • 6.86 kB
/** * Error Handling Demo for Ultimate CRUD * Demonstrates proper HTTP status codes for database validation errors * * @license MIT * @copyright 2025 cnos-dev * @author Harish Kashyap (CNOS Dev) */ const express = require('express'); const { Sequelize } = require('sequelize'); const UltimateCrud = require('../index'); const app = express(); app.use(express.json()); // SQLite database for demo const sequelize = new Sequelize({ dialect: 'sqlite', storage: 'error-demo.db', logging: false }); // Entity configuration with comprehensive error messages const entities = [ { name: 'users', type: 'table', route: '/api/users', responseMessages: { 200: 'Users retrieved successfully', 201: 'User created successfully', 400: 'Invalid request data', 404: 'User not found', 409: 'User with this email or username already exists', 422: 'User data validation failed', 500: 'Internal server error occurred' } }, { name: 'posts', type: 'table', route: '/api/posts', associations: [ { type: 'belongsTo', target: 'users', foreignKey: 'authorId', as: 'author' } ], responseMessages: { 200: 'Posts retrieved successfully', 201: 'Post created successfully', 404: 'Post not found', 409: 'Post with this title already exists', 422: 'Post data validation failed or referenced user does not exist', 500: 'Server error while processing post' } } ]; async function setupDatabase() { console.log('šŸ”§ Setting up database with constraints...'); try { // Create users table with constraints await sequelize.query(` CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, username VARCHAR(50) NOT NULL UNIQUE, email VARCHAR(100) NOT NULL UNIQUE, firstName VARCHAR(50) NOT NULL, lastName VARCHAR(50), age INTEGER CHECK (age >= 0 AND age <= 150), created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ) `); // Create posts table with foreign key constraint await sequelize.query(` CREATE TABLE IF NOT EXISTS posts ( id INTEGER PRIMARY KEY AUTOINCREMENT, title VARCHAR(200) NOT NULL UNIQUE, content TEXT NOT NULL, author_id INTEGER NOT NULL, published BOOLEAN DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (author_id) REFERENCES users(id) ) `); console.log('āœ… Database tables created with constraints'); } catch (error) { console.error('āŒ Database setup failed:', error.message); throw error; } } async function startServer() { try { // Setup database await setupDatabase(); // Initialize Ultimate CRUD const ultimateCrud = UltimateCrud.create({ app, sequelize, entities, enableGraphQL: false, // Disable for this demo enableRest: true, enableOpenAPI: true, syncDatabase: false // We manually created tables }); await ultimateCrud.initialize(); const PORT = process.env.PORT || 3000; app.listen(PORT, () => { console.log(`šŸš€ Error Handling Demo Server running on http://localhost:${PORT}`); console.log(`šŸ“‹ OpenAPI Spec: http://localhost:${PORT}/openapi.json`); console.log('\nšŸ“– Error Handling Demo Scenarios:'); console.log('====================================='); console.log('\n1ļøāƒ£ SUCCESS - Create valid user:'); console.log(`curl -X POST http://localhost:${PORT}/api/users \\`); console.log(` -H "Content-Type: application/json" \\`); console.log(` -d '{"username":"john_doe","email":"john@example.com","firstName":"John","lastName":"Doe","age":25}'`); console.log('\n2ļøāƒ£ ERROR 409 - Duplicate email/username:'); console.log(`curl -X POST http://localhost:${PORT}/api/users \\`); console.log(` -H "Content-Type: application/json" \\`); console.log(` -d '{"username":"john_doe","email":"john@example.com","firstName":"Jane","lastName":"Smith","age":30}'`); console.log('\n3ļøāƒ£ ERROR 422 - Validation failure (missing required field):'); console.log(`curl -X POST http://localhost:${PORT}/api/users \\`); console.log(` -H "Content-Type: application/json" \\`); console.log(` -d '{"username":"jane_doe","email":"jane@example.com","age":25}'`); console.log('\n4ļøāƒ£ ERROR 422 - Invalid data (age constraint):'); console.log(`curl -X POST http://localhost:${PORT}/api/users \\`); console.log(` -H "Content-Type: application/json" \\`); console.log(` -d '{"username":"invalid_user","email":"invalid@example.com","firstName":"Invalid","age":-5}'`); console.log('\n5ļøāƒ£ ERROR 422 - Foreign key constraint (non-existent user):'); console.log(`curl -X POST http://localhost:${PORT}/api/posts \\`); console.log(` -H "Content-Type: application/json" \\`); console.log(` -d '{"title":"Test Post","content":"Post content","authorId":999}'`); console.log('\n6ļøāƒ£ SUCCESS - Valid post creation (create user first):'); console.log(`curl -X POST http://localhost:${PORT}/api/posts \\`); console.log(` -H "Content-Type: application/json" \\`); console.log(` -d '{"title":"My First Post","content":"This is my first post content","authorId":1}'`); console.log('\n7ļøāƒ£ ERROR 409 - Duplicate post title:'); console.log(`curl -X POST http://localhost:${PORT}/api/posts \\`); console.log(` -H "Content-Type: application/json" \\`); console.log(` -d '{"title":"My First Post","content":"Different content","authorId":1}'`); console.log('\n8ļøāƒ£ ERROR 404 - Update non-existent user:'); console.log(`curl -X PUT http://localhost:${PORT}/api/users/999 \\`); console.log(` -H "Content-Type: application/json" \\`); console.log(` -d '{"firstName":"Updated"}'`); console.log('\nšŸ’” Expected HTTP Status Codes:'); console.log(' 200 āœ… Success'); console.log(' 201 āœ… Created'); console.log(' 404 āŒ Not Found'); console.log(' 409 āŒ Conflict (unique constraint violation)'); console.log(' 422 āŒ Unprocessable Entity (validation/FK errors)'); console.log(' 500 āŒ Internal Server Error'); console.log('\nšŸ” Test the scenarios above to see proper error handling!'); }); } catch (error) { console.error('āŒ Server startup failed:', error.message); process.exit(1); } } // Start the demo server if (require.main === module) { startServer(); } module.exports = { startServer };