🚨 Error Handling
Proper error handling is crucial for building robust backend services. The Nodeblocks SDK provides comprehensive error handling patterns that ensure consistent, user-friendly error responses across all services.
🎯 Error Response Format
All Nodeblocks services return errors in a consistent JSON format:
{
"error": {
"message": "Error message description",
"data": ["Additional error details"]
}
}
Validation Errors
When request validation fails, additional details are included:
{
"error": {
"message": "Validation Error",
"data": [
"request body must have required property 'name'",
"request body must have required property 'email'",
"request body must NOT have additional properties"
]
}
}
📋 Common Error Codes
400 Bad Request
- Validation Error - Invalid request body format or missing required fields
- Failed to create [entity] - Database insert operation failed to return an inserted ID
- Failed to update [entity] - Update operation doesn't modify any data (no changes detected)
- Failed to delete [entity] - Database deletion operation failed
401 Unauthorized
- token could not be verified - Missing or invalid authorization token
- Authentication failed - Missing or invalid authentication token
- Token fails security check - Token security validation failed
403 Forbidden
- User is not authorized to access this resource - User lacks required permissions
- User is not authorized to access this [entity] - User lacks specific entity permissions
404 Not Found
- [Entity] not found - Entity doesn't exist for the requested operation
- [Entity] does not exist - Entity doesn't exist for the requested operation
409 Conflict
- [Entity] already exists - Entity with the same identifier already exists
- User with this email already exists - Duplicate user email
500 Internal Server Error
- Failed to create [entity] - Database connection issues or unexpected failures during creation
- Failed to get [entity] - Database connection issues or unexpected failures during retrieval
- Failed to find [entities] - Database connection issues, invalid filter syntax, or unexpected failures during listing
- Failed to update [entity] - Database connection issues or unexpected failures during update
- Failed to delete [entity] - Database connection issues or unexpected failures during deletion
🔧 Service-Specific Error Patterns
Authentication Service Errors
{
"error": {
"message": "token could not be verified"
}
}
{
"error": {
"message": "Authentication failed"
}
}
User Service Errors
{
"error": {
"message": "User profile not found"
}
}
{
"error": {
"message": "Identity is not authorized to access this resource"
}
}
Organization Service Errors
{
"error": {
"message": "Organization not found"
}
}
{
"error": {
"message": "Failed to create organization"
}
}
Product Service Errors
{
"error": {
"message": "Product not found"
}
}
{
"error": {
"message": "Failed to create product"
}
}
Category Service Errors
{
"error": {
"message": "Category does not exist"
}
}
{
"error": {
"message": "Failed to create category"
}
}
Attribute Service Errors
{
"error": {
"message": "Attribute group not found"
}
}
{
"error": {
"message": "Failed to create attribute group"
}
}
Order Service Errors
{
"error": {
"message": "Order not found"
}
}
{
"error": {
"message": "Failed to create order"
}
}
Chat Service Errors
{
"error": {
"message": "Channel not found"
}
}
{
"error": {
"message": "Chat message not found"
}
}
📐️ Error Handling Best Practices
1. Consistent Error Messages
Use consistent, user-friendly error messages across all services:
// ✅ Good: Clear, actionable error messages
"User profile not found"
"Failed to create organization"
"Validation Error"
// ❌ Avoid: Technical or unclear messages
"Database connection failed"
"Internal server error"
"Something went wrong"
2. Proper HTTP Status Codes
Use appropriate HTTP status codes for different error types:
- 400 - Bad Request (validation errors, missing fields)
- 401 - Unauthorized (authentication failures)
- 403 - Forbidden (authorization failures)
- 404 - Not Found (entity doesn't exist)
- 409 - Conflict (duplicate entities)
- 500 - Internal Server Error (database issues, unexpected failures)
3. Validation Error Details
Include specific validation error details in the data array:
{
"error": {
"message": "Validation Error",
"data": [
"request body must have required property 'name'",
"request body must have required property 'email'",
"request body must NOT have additional properties"
]
}
}
4. Authentication Error Handling
Use validators to handle authentication errors automatically:
import { primitives, validators } from '@nodeblocks/backend-sdk';
const { withRoute } = primitives;
const { isAuthenticated } = validators;
// Validators automatically throw NodeblocksError with appropriate status codes
export const protectedRoute = withRoute({
method: 'GET',
path: '/protected',
validators: [isAuthenticated()], // Throws 401 if not authenticated
handler: protectedHandler,
});
For custom authentication checks in handlers or validators:
import { primitives } from '@nodeblocks/backend-sdk';
const validateAuth = async (payload: primitives.RouteHandlerPayload) => {
const tokenInfo = await payload.context.authenticate(payload);
if (!tokenInfo) {
throw new primitives.NodeblocksError(
401,
'token could not be verified',
'validateAuth'
);
}
};
5. Authorization Error Handling
Use validators for authorization checks:
import { primitives, validators } from '@nodeblocks/backend-sdk';
const { withRoute } = primitives;
const { validateResourceAccess, checkIdentityType } = validators;
// Check identity type (e.g., admin only)
export const adminRoute = withRoute({
method: 'GET',
path: '/admin',
validators: [
checkIdentityType(['admin']), // Throws 403 if not admin
],
handler: adminHandler,
});
// Or check resource access
export const resourceRoute = withRoute({
method: 'GET',
path: '/resource/:id',
validators: [
validateResourceAccess(['admin', 'self']), // Throws 403 if not authorized
],
handler: resourceHandler,
});
For custom authorization in validators:
import { primitives } from '@nodeblocks/backend-sdk';
const checkAdminRole = async (payload: primitives.RouteHandlerPayload) => {
const identity = payload.context.data?.identity;
if (!identity || identity.typeId !== 'admin') {
throw new primitives.NodeblocksError(
403,
'User is not authorized to access this resource',
'checkAdminRole'
);
}
};
⚙️ Error Middleware Setup
To ensure consistent error handling across your application, use the nodeBlocksErrorMiddleware:
import express from 'express';
import { middlewares, services, drivers } from '@nodeblocks/backend-sdk';
const { nodeBlocksErrorMiddleware } = middlewares;
const { userService, organizationService } = services;
const { withMongo } = drivers;
const connectToDatabase = withMongo('mongodb://localhost:27017', 'dev', 'user', 'password');
express()
.use(userService({
...(await connectToDatabase('users')),
...(await connectToDatabase('identity'))
}))
.use(organizationService({
...(await connectToDatabase('organizations')),
...(await connectToDatabase('identity'))
}))
.use(nodeBlocksErrorMiddleware()) // Must be last
.listen(8089, () => console.log('Server running'));
⚠️ Important: Always add
nodeBlocksErrorMiddleware()after your routes and services to ensure all errors are properly formatted as JSON responses.
🔍 Error Debugging
Development Mode
In development mode, additional error details may be included:
{
"error": {
"message": "Database connection failed",
"stack": "Error: Database connection failed\n at createUser...",
"data": {
"operation": "createUser",
"timestamp": "2024-05-28T09:41:22.552Z"
}
}
}
Production Mode
In production, only essential error information is returned:
{
"error": {
"message": "Internal server error"
}
}