Skip to main content
Version: 🚧 Canary

🚨 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"
}
}