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
JavaScript
/**
* 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 };