@@ -557,6 +557,103 @@ if "enable_feature" not in driver_features:
557557 driver_features["enable_feature"] = OPTIONAL_PACKAGE_INSTALLED
558558` ` `
559559
560+ # ## Error Handling in Type Handlers
561+
562+ When implementing type handlers that register optional database extensions, distinguish between expected and unexpected failures :
563+
564+ **Expected Failures** (graceful degradation) → **DEBUG level**:
565+
566+ - Database extension not enabled (e.g., `CREATE EXTENSION vector` not run)
567+ - Optional Python package not installed
568+ - Database version doesn't support the feature
569+
570+ **Unexpected Failures** (need investigation) → **WARNING or ERROR level**:
571+
572+ - Network errors during registration
573+ - Permission issues
574+ - Invalid configuration
575+ - Unknown exceptions
576+
577+ **Pattern for Extension Registration**:
578+
579+ ` ` ` python
580+ async def register_optional_extension(connection):
581+ """Register optional database extension support.
582+
583+ Gracefully handles missing extensions with DEBUG logging.
584+ """
585+ if not OPTIONAL_PACKAGE_INSTALLED:
586+ logger.debug("Optional package not installed - skipping extension support")
587+ return
588+
589+ try:
590+ import optional_package
591+ await optional_package.register(connection)
592+ logger.debug("Registered optional extension support")
593+ except SpecificExpectedError as error:
594+ message = str(error).lower()
595+ if "extension not found" in message or "type not found" in message:
596+ logger.debug("Skipping extension registration - extension not enabled in database")
597+ return
598+ logger.warning("Unexpected error during extension registration: %s", error)
599+ except Exception:
600+ logger.exception("Failed to register optional extension")
601+ ` ` `
602+
603+ **Real-World Example - PostgreSQL pgvector**:
604+
605+ Different PostgreSQL drivers raise different error messages for the same condition (pgvector extension not enabled) :
606+
607+ ` ` ` python
608+ # AsyncPG - raises ValueError("unknown type: public.vector")
609+ async def register_pgvector_support(connection):
610+ if not PGVECTOR_INSTALLED:
611+ logger.debug("pgvector not installed - skipping vector type support")
612+ return
613+
614+ try:
615+ import pgvector.asyncpg
616+ await pgvector.asyncpg.register_vector(connection)
617+ logger.debug("Registered pgvector support on asyncpg connection")
618+ except ValueError as exc:
619+ message = str(exc).lower()
620+ if "unknown type" in message and "vector" in message:
621+ logger.debug("Skipping pgvector registration - extension not enabled in database")
622+ return
623+ logger.warning("Unexpected error during pgvector registration: %s", exc)
624+ except Exception:
625+ logger.exception("Failed to register pgvector support")
626+
627+ # Psycopg - raises ValueError("vector type not found in the database")
628+ def register_pgvector_sync(connection):
629+ if not PGVECTOR_INSTALLED:
630+ logger.debug("pgvector not installed - skipping vector type handlers")
631+ return
632+
633+ try:
634+ import pgvector.psycopg
635+ pgvector.psycopg.register_vector(connection)
636+ logger.debug("Registered pgvector type handlers on psycopg sync connection")
637+ except ValueError as error:
638+ message = str(error).lower()
639+ if "vector type not found" in message:
640+ logger.debug("Skipping pgvector registration - extension not enabled in database")
641+ return
642+ logger.warning("Unexpected error during pgvector registration: %s", error)
643+ except Exception:
644+ logger.exception("Failed to register pgvector for psycopg sync")
645+ ` ` `
646+
647+ **Key Principles**:
648+
649+ 1. Check for **specific error messages** to identify expected vs unexpected failures
650+ 2. Use **DEBUG** for expected graceful degradation (extension not available)
651+ 3. Use **WARNING** for unexpected issues during optional feature setup
652+ 4. Use **ERROR/exception** for critical failures
653+ 5. Provide **clear, actionable log messages**
654+ 6. Never break application flow on expected failures
655+ 7. Match error message checks to **actual driver behavior** (different drivers raise different messages)
656+
560657# ## Examples from Existing Adapters
561658
562659**Oracle NumPy VECTOR Support** (`oracledb/_numpy_handlers.py`):
0 commit comments