Skip to content

TASK-P1-004: Design Exception Hierarchy #2866

@robfrank

Description

@robfrank

Priority: HIGH
Effort: 7 days (1.5 weeks)
Phase: Phase 1 - Foundation
Week: 3-4 (Exception Handling)
Status: Design Revised - Addressing Architectural Feedback


Overview

Design and implement a standardized exception handling framework for ArcadeDB that maintains proper layered architecture, uses string-based error codes (no numeric codes), and provides clear exception translation at module boundaries.

Problem Statement

Initial Implementation Issues (PR #3048)

The first implementation introduced architectural violations:

  1. ❌ HTTP Concepts in Engine Module

    • ArcadeDBException.getHttpStatus() method
    • Engine module aware of HTTP/server concepts
    • Violates layering: engine should not know about HTTP
  2. ❌ Network Error Codes in Engine Module

    • ErrorCode enum contained Network category (6000-6999)
    • Engine module aware of network module concepts
    • Violates dependency flow: engine → network → server
  3. ❌ Numeric Code Coordination

    • Error codes used numeric ranges (1xxx, 2xxx, 6xxx)
    • Required coordination across modules
    • Unnecessary coupling, harder to extend

Luca's Feedback (2025-12-21)

"Not nice the basic exception has concepts of http here"
"Same here, the engine base model now has concepts from other modules (network)"
"Instead of contaminating all the exceptions with HTTP concept and codes, I'd prefer to have 1 method that returns the Http code from any exception, and it should be in the http server."


Revised Solution Design

Core Principles

  1. Exception Translation at Module Boundaries - Each module translates exceptions when crossing boundaries
  2. String-Based Error Codes - Use enum names directly (no numeric codes)
  3. Category-Based Organization - Group errors by category for clarity
  4. Zero Cross-Module Dependencies - Each module defines only its own exceptions

Architecture

┌─────────────────────────────────────────────┐
│ Server Module (arcadedb-server)             │
│ - HttpExceptionTranslator                   │
│   ↳ Maps ANY exception → HTTP status        │
│ - NO HTTP concepts in engine/network        │
└─────────────────────────────────────────────┘
                    ↑
┌─────────────────────────────────────────────┐
│ Network Module (arcadedb-network)           │
│ - NetworkErrorCode enum (string-based)      │
│ - NetworkException                           │
│ - NetworkExceptionTranslator                 │
└─────────────────────────────────────────────┘
                    ↑
┌─────────────────────────────────────────────┐
│ Engine Module (arcadedb-engine)             │
│ - ArcadeDBException (NO HTTP, NO Network)   │
│ - ErrorCode enum (string-based)             │
│ - ErrorCategory enum                         │
└─────────────────────────────────────────────┘

Why String-Based Error Codes?

Benefits:

  • Simpler Module Separation - No numeric range coordination
  • More Readable - DB_NOT_FOUND vs 1001
  • Modern API Design - Follows Stripe, AWS, GitHub standards
  • Easier Extension - Third parties can add errors freely
  • Cleaner Implementation - No numeric lookup maps

Example:

// Engine Module
public enum ErrorCode {
    DB_NOT_FOUND(ErrorCategory.DATABASE, "Database not found"),
    TX_TIMEOUT(ErrorCategory.TRANSACTION, "Transaction timeout"),
    QUERY_SYNTAX_ERROR(ErrorCategory.QUERY, "Query syntax error"),
    // ... NO network errors here
}

// Network Module (separate)
public enum NetworkErrorCode {
    CONNECTION_ERROR("Connection error"),
    CONNECTION_LOST("Connection lost"),
    REPLICATION_ERROR("Replication error"),
    // ... network-specific codes
}

JSON Response:

{
  "error": "DB_NOT_FOUND",
  "category": "Database",
  "message": "Database 'mydb' not found",
  "timestamp": 1704834567890,
  "context": {
    "databaseName": "mydb"
  }
}

Implementation Plan

Phase 1: Engine Module Cleanup (2 days)

Remove Architectural Violations:

  • Remove getHttpStatus() from ArcadeDBException
  • Remove getHttpStatus() from all exception subclasses
  • Remove Network error codes (6xxx) from ErrorCode enum
  • Redesign ErrorCode without numeric codes
  • Create ErrorCategory enum
  • Update ArcadeDBException:
    • Remove: getErrorCodeValue(), getHttpStatus()
    • Add: getErrorCodeName(), getErrorCategoryName()
  • Update exception subclasses with new error code names:
    • DATABASE_NOT_FOUNDDB_NOT_FOUND
    • TRANSACTION_TIMEOUTTX_TIMEOUT
    • etc.

Files to Modify:

  • engine/src/main/java/com/arcadedb/exception/ArcadeDBException.java
  • engine/src/main/java/com/arcadedb/exception/ErrorCode.java
  • engine/src/main/java/com/arcadedb/exception/DatabaseException.java
  • engine/src/main/java/com/arcadedb/exception/TransactionException.java
  • engine/src/main/java/com/arcadedb/exception/QueryException.java
  • All other exception subclasses

Files to Create:

  • engine/src/main/java/com/arcadedb/exception/ErrorCategory.java

Phase 2: Network Module (1 day)

Add Network-Specific Exceptions:

  • Create NetworkErrorCode enum
  • Create NetworkException class
  • Create NetworkExceptionTranslator utility
  • Update network code to use new exceptions

Files to Create:

  • network/src/main/java/com/arcadedb/network/exception/NetworkErrorCode.java
  • network/src/main/java/com/arcadedb/network/exception/NetworkException.java
  • network/src/main/java/com/arcadedb/network/exception/NetworkExceptionTranslator.java

Phase 3: Server Module (1.5 days)

Add HTTP Translation Layer:

  • Create HttpExceptionTranslator utility
  • Implement HTTP status mapping for all error codes
  • Update all HTTP handlers to use translator
  • Replace exception.getHttpStatus() with HttpExceptionTranslator.getHttpStatus(exception)

Files to Create:

  • server/src/main/java/com/arcadedb/server/http/HttpExceptionTranslator.java

Files to Modify:

  • All HTTP handler classes in server/src/main/java/com/arcadedb/server/http/handler/

Phase 4: Testing & Migration (2 days)

Code Migration:

  • Search and replace all getErrorCodeValue() usages
  • Search and replace all getHttpStatus() usages on exceptions
  • Update all error code enum references
  • Update error code checks in conditionals
  • Update test assertions

Testing:

  • Run full test suite
  • Fix compilation errors
  • Performance testing
  • Integration testing

Phase 5: Documentation (0.5 days)

  • Update ADR-001 with new architecture
  • Add "Why no numeric codes?" section
  • Create error code reference table
  • Update JavaDoc
  • Add architecture diagram
  • Create migration guide

Files Structure

Engine Module

engine/src/main/java/com/arcadedb/exception/
├── ArcadeDBException.java          # Base class (NO HTTP, NO Network)
├── ErrorCode.java                   # String-based codes (DB_*, TX_*, QUERY_*, etc.)
├── ErrorCategory.java               # NEW: Category enum
├── DatabaseException.java           # Updated
├── TransactionException.java        # Updated
├── QueryException.java              # Updated
├── SecurityException.java           # Updated
├── StorageException.java            # Updated
├── SchemaException.java             # Updated
├── IndexException.java              # Updated
├── GraphException.java              # Updated
├── ImportException.java             # Updated
├── ExportException.java             # Updated
└── InternalException.java           # Updated

Network Module

network/src/main/java/com/arcadedb/network/exception/
├── NetworkErrorCode.java            # NEW: Network-specific codes
├── NetworkException.java            # NEW: Network exception
└── NetworkExceptionTranslator.java  # NEW: Boundary translation

Server Module

server/src/main/java/com/arcadedb/server/http/
└── HttpExceptionTranslator.java     # NEW: HTTP translation ONLY HERE

Documentation

docs/architecture/
├── ADR-001-exception-handling.md    # Updated with new design
└── exception-architecture.md        # NEW: Architecture diagram

Acceptance Criteria

Architecture ✅

  • Engine module has ZERO references to HTTP concepts
  • Engine module has ZERO references to Network concepts
  • Engine module has ZERO numeric error code coordination
  • Network module defines own error codes independently
  • Server module handles HTTP translation exclusively
  • Clean exception translation at module boundaries

Implementation ✅

  • All error codes are string-based (enum names)
  • ErrorCategory enum created
  • HttpExceptionTranslator created in server module
  • NetworkException created in network module
  • All HTTP handlers updated to use translator
  • No getHttpStatus() methods in engine/network modules

Code Quality ✅

  • All tests pass
  • No compilation warnings
  • No dependency violations (verify with JDepend)
  • Code coverage maintained or improved
  • Error code enum names follow consistent naming pattern

Documentation ✅

  • ADR-001 updated with rationale
  • Error code reference documentation
  • Architecture diagram added
  • JavaDoc complete for all new classes
  • Migration guide in PR description

Timeline

  • Phase 1 (Engine Cleanup): 2 days
  • Phase 2 (Network Module): 1 day
  • Phase 3 (Server Module): 1.5 days
  • Phase 4 (Testing & Migration): 2 days
  • Phase 5 (Documentation): 0.5 days

Total: ~7 days (1.5 weeks)


References


Next Steps

  1. ✅ Get team approval on revised design
  2. ⏳ Implement Phase 1 (Engine cleanup)
  3. ⏳ Implement Phase 2 (Network module)
  4. ⏳ Implement Phase 3 (Server module)
  5. ⏳ Update PR TASK-P1-004: Design Exception Hierarchy #3048 with new implementation

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions