doctrine / dbal

Doctrine Database Abstraction Layer
https://www.doctrine-project.org/projects/dbal.html
MIT License
9.48k stars 1.34k forks source link

OCI8 driver does not check result from oci_parse, relies on disabled assert in production #6595

Open segrax opened 6 days ago

segrax commented 6 days ago

Bug Report

Q A
Version 4.2.1

Summary

The Oracle (OCI8) driver uses assert to verify the result from oci_parse.

By default (since PHP7), assert is disabled in production environments, which means the validation is never executed in prod. Unlike other drivers that handle this check by throwing exceptions, the OCI8 driver relies on assert, resulting in warnings in the log, and no way of catching the lost connection

        $statement = oci_parse($this->connection, $visitor->getSQL());
        assert(is_resource($statement));

        return new Statement($this->connection, $statement, $visitor->getParameterMap(), $this->executionMode);

Current behavior

In production, if oci_parse fails (e.g., due to a connection issue), the assert statement is bypassed, leading to PHP warnings rather than controlled exceptions. This results in the following warning:

PHP Warning: oci_parse(): ORA-03114: not connected to ORACLE in /srv/app/vendor/doctrine/dbal/src/Driver/OCI8/Connection.php on line 57

Expected behavior

The Oracle driver should handle oci_parse failures consistently with other drivers by checking the result and throwing an appropriate exception if oci_parse fails. This would ensure reliable error handling across all environments

How to reproduce

  1. Disable assertions in your production-like environment
  2. Use the OCI8 driver to connect to an Oracle database
  3. Trigger a connection issue (e.g., disconnect or shutdown the Oracle server)
  4. Observe that instead of an exception, a PHP warning is issued, and the error is not handled as expected
derrabus commented 6 days ago

PR welcome, I guess.