Laminas-db sqlsrv exceptions, how to read error text

My app uses laminas-db and SQL Server. When there’s a SQL error condition, this code in src\Adapter\Driver\Sqlsrv\Connection handles it:

        // if the returnValue is something other than a Sqlsrv_result, bypass wrapping it
        if ($returnValue === false) {
            $errors = sqlsrv_errors();
            // ignore general warnings
            if ($errors[0]['SQLSTATE'] !== '01000') {
                throw new Exception\RuntimeException(
                    'An exception occurred while trying to execute the provided $sql',
                    null,
                    new ErrorException($errors)
                );
            }
        }

As you can see, it doesn’t retrieve $errors[N][‘message’] and concatenate anything to the exception’s message, but it does take the entire array from sqlsrv_errors(), and pass it to the constructor of src\Adapter\Driver\Sqlsrv\Exception\ErrorException, and use that as the “previous” in the thrown exception. However, all ErrorException does with that argument is store it to a member array, which is great - but it’s protected, and doesn’t appear to implement any way to read it.

<?php

namespace Laminas\Db\Adapter\Driver\Sqlsrv\Exception;

use Laminas\Db\Adapter\Exception;

use function sqlsrv_errors;

class ErrorException extends Exception\ErrorException implements ExceptionInterface
{
    /**
     * Errors
     *
     * @var array
     */
    protected $errors = [];

    /**
     * Construct
     *
     * @param  bool $errors
     */
    public function __construct($errors = false)
    {
        $this->errors = $errors === false ? sqlsrv_errors() : $errors;
    }
}

Debugging confirms the SQL errors don’t end up in the Exception message, or in the trace, they seem to only be sealed in this protected array.

So the problem ultimately here is that my app logs the same useless message “An exception occurred while trying to execute the provided $sql” without the actual sqlsrv error messages.

While it would be easy enough to patch laminas-db, I feel it’s more likely I am just missing something. What is the intended way for applications to access the error messages from RDBMS?

Thank you!

This seems to be a very quiet forum, but for posterity this is how I ended up patching laminas-db:

--- a/vendor/laminas/laminas-db/src/Adapter/Driver/Sqlsrv/Exception/ErrorException.php
+++ b/patches/ErrorException.php
@@ -23,5 +23,9 @@ class ErrorException extends Exception\ErrorException implements ExceptionInterf
     public function __construct($errors = false)
     {
         $this->errors = $errors === false ? sqlsrv_errors() : $errors;
+        $this->message = "SQLSrv Errors: ";
+        foreach ($this->errors as $errNum => $error) {
+            $this->message .= "Error #".$errNum." SQLSTATE ".$error['SQLSTATE']." code ".$error['code']." message ".$error['message'];
+        }
     }
 }

My exceptions now have all the SQL error information in them. It still seems like I was missing something, but if not, I suggest an enhancement of this nature be made to laminas-db.

On the contrary, it is well used. According to the statistics, people read a lot and there is a core of users that always tries to help and does it quickly.
And the forum is just one of several channels:

https://getlaminas.org/participate

That’s not likely to happen because laminas-db is in security-only maintenance Mode:

This package is considered feature-complete, and is now in security-only maintenance mode, following a decision by the Technical Steering Committee.
If you have a security issue, please follow our security reporting guidelines.
If you wish to take on the role of maintainer, please nominate yourself

That’s great information, thank you. I was looking only at laminas-db topics, and the package being security-only explains it. Does that status imply an approaching end of life or merely an outcome of the “feature complete” state? Have a great day.

There 's no end of life in sight. It 's just feature-complete. The package does what it 's supposed to do and it does it very well.

Do you miss something?

Hi @ezkimo. My original issue with laminas-db is described in the opening post of the thread. I originally sought support moreso than really saying there was any shortcoming. I returned to share the patch I ended up using for future reference, in case it really is a limitation in laminas-db rather than a lack of understanding on my part. If it’s a package limitation, and future changes are now limited to security only, I am happy to keep patching it on own project and hope my forum thread is useful to someone. If the problem is my lack of understanding, I’d be pleased to be corrected instead and have that knowledge published as well. That was the spirit of the post. Thank you.

1 Like