This document describes the comprehensive validation and error handling system implemented for all API endpoints in the GXQ Studio platform.
Provides comprehensive input validation for all API endpoints.
- Type validation: string, number, boolean, array, object, email, url, solana-address
- Required field checking: Ensure mandatory fields are present
- Range validation: Min/max length for strings, min/max value for numbers
- Pattern matching: Regex validation for complex formats
- Enum validation: Restrict values to predefined set
- Custom validation: Custom validation functions
- Sanitization: Remove dangerous characters and HTML tags
- Rate limiting: In-memory rate limiting (use Redis in production)
import { validateRequest, ValidationRule } from '../middleware/validation';
const rules: ValidationRule[] = [
{
field: 'username',
type: 'string',
required: true,
min: 3,
max: 50,
},
{
field: 'walletAddress',
type: 'solana-address',
required: true,
},
{
field: 'amount',
type: 'number',
required: true,
min: 0,
custom: (value) => value > 0 || 'Amount must be positive',
},
];
// In your endpoint handler
const validation = validateRequest(req.body, rules);
if (!validation.valid) {
return res.status(400).json({
success: false,
error: 'Validation failed',
details: validation.errors,
});
}Provides centralized error handling with consistent error responses.
ValidationError(400): Input validation failuresAuthenticationError(401): Missing or invalid authenticationAuthorizationError(403): Insufficient permissionsNotFoundError(404): Resource not foundRateLimitError(429): Rate limit exceededConfigurationError(500): Missing environment variablesExternalServiceError(503): External service failures
import { withErrorHandler, ValidationError, checkRequiredEnv } from '../middleware/errorHandler';
export default withErrorHandler(async (req, res) => {
// Check required environment variables
checkRequiredEnv(['SOLANA_RPC_URL', 'WALLET_PRIVATE_KEY']);
// Your endpoint logic
if (!req.body.username) {
throw new ValidationError('Username is required');
}
// Automatic error handling and consistent responses
return res.status(200).json({ success: true, data: result });
});Handles Cross-Origin Resource Sharing for API endpoints.
- Origin validation: Whitelist allowed origins
- Credentials support: Enable/disable credentials
- Preflight handling: Automatic OPTIONS request handling
- Environment-aware: Different configs for dev/prod
import { withCors, getCorsOptions } from '../middleware/cors';
export default withCors(async (req, res) => {
// Your endpoint logic
return res.status(200).json({ success: true });
}, getCorsOptions());-
Validate Input
- Check required fields
- Validate data types
- Sanitize user input
- Validate Solana addresses
-
Handle Errors
- Use consistent error format
- Log errors with context
- Return appropriate HTTP status codes
- Never expose sensitive information
-
Implement Rate Limiting
- Protect against abuse
- Use appropriate limits per endpoint
- Return
429with reset time
-
Check Authentication (where required)
- Verify JWT tokens
- Check token expiration
- Validate user permissions
-
Log Requests
- Log important operations
- Include request IDs
- Log errors with full context
All errors follow this standard format:
{
"success": false,
"error": "ERROR_CODE",
"message": "Human-readable error message",
"code": "ERROR_CODE",
"details": {
"field": "username",
"reason": "Username must be at least 3 characters"
},
"timestamp": 1703001234567,
"requestId": "req_abc123"
}{
field: 'walletAddress',
type: 'solana-address',
required: true,
}{
field: 'amount',
type: 'number',
required: true,
min: 0,
custom: (value) => value <= 1000000 || 'Amount too large',
}{
field: 'command',
type: 'string',
required: true,
enum: ['start', 'stop', 'pause', 'resume'],
}| Endpoint | Limit | Window |
|---|---|---|
/api/health |
60 requests | 1 minute |
/api/admin/auth |
5 requests | 15 minutes |
/api/monitor |
10 requests | 1 minute |
/api/execute |
5 requests | 1 minute |
/api/admin/* |
30 requests | 1 minute |
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1703001294567
Run the endpoint validation script:
npm run validate-endpoints http://localhost:3000curl http://localhost:3000/api/healthcurl -X POST http://localhost:3000/api/admin/auth \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"password"}'curl http://localhost:3000/api/admin/metrics \
-H "Authorization: Bearer YOUR_JWT_TOKEN"- ✅ Always validate user input
- ✅ Use type-safe validation
- ✅ Sanitize HTML and scripts
- ✅ Validate Solana addresses before use
- ✅ Check array/object sizes
- ✅ Never expose stack traces in production
- ✅ Log errors with full context
- ✅ Use appropriate HTTP status codes
- ✅ Return generic error messages to users
- ✅ Log sensitive operations
- ✅ Use JWT with expiration
- ✅ Implement rate limiting on auth endpoints
- ✅ Never log passwords or tokens
- ✅ Use HTTPS in production
- ✅ Rotate secrets regularly
- ✅ Implement per-IP rate limiting
- ✅ Use stricter limits for auth endpoints
- ✅ Return clear error messages
- ✅ Consider using Redis for distributed systems
- ✅ Monitor for abuse patterns
# Required for all endpoints
SOLANA_RPC_URL=https://api.mainnet-beta.solana.com
WALLET_PRIVATE_KEY=your_base58_private_key
# Required for admin endpoints
ADMIN_USERNAME=admin
ADMIN_PASSWORD=strong_password
JWT_SECRET=your_32_character_secret
# Optional: Enhanced security
CRON_SECRET=your_cron_secretimport { checkRequiredEnv } from './middleware/errorHandler';
// Check at startup
checkRequiredEnv([
'SOLANA_RPC_URL',
'WALLET_PRIVATE_KEY',
'ADMIN_USERNAME',
'ADMIN_PASSWORD',
'JWT_SECRET',
]);console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
console.log('Headers:', req.headers);
console.log('Body:', req.body);import { logError } from './middleware/errorHandler';
logError(error, {
endpoint: req.url,
method: req.method,
ip: getClientIp(req),
userId: req.user?.id,
});Monitor these metrics:
- Response times
- Error rates
- Rate limit hits
- Authentication failures
- RPC latency
Solution: Ensure you're checking the details field in error responses.
Solution: Check that your domain is in the allowed origins list.
Solution: Adjust rate limit parameters or implement user-based limits.
Solution:
- Check RPC connection
- Review database queries
- Implement caching
- Use connection pooling
- ✅ Implement validation for all endpoints
- ✅ Add comprehensive error handling
- ✅ Set up rate limiting
- ✅ Configure CORS properly
- ✅ Test all endpoints
- ✅ Monitor errors in production
- ✅ Document API changes