How can I get the full string of PHP’s getTraceAsString()?

24,306

Solution 1

I created this function to return a stack trace with no truncated strings:

function getExceptionTraceAsString($exception) {
    $rtn = "";
    $count = 0;
    foreach ($exception->getTrace() as $frame) {
        $args = "";
        if (isset($frame['args'])) {
            $args = array();
            foreach ($frame['args'] as $arg) {
                if (is_string($arg)) {
                    $args[] = "'" . $arg . "'";
                } elseif (is_array($arg)) {
                    $args[] = "Array";
                } elseif (is_null($arg)) {
                    $args[] = 'NULL';
                } elseif (is_bool($arg)) {
                    $args[] = ($arg) ? "true" : "false";
                } elseif (is_object($arg)) {
                    $args[] = get_class($arg);
                } elseif (is_resource($arg)) {
                    $args[] = get_resource_type($arg);
                } else {
                    $args[] = $arg;
                }   
            }   
            $args = join(", ", $args);
        }
        $rtn .= sprintf(
            "#%s %s(%s): %s%s%s(%s)\n",
            $count,
            $frame['file'],
            $frame['line'],
            isset($frame['class']) ? $frame['class'] : '',
            isset($frame['type']) ? $frame['type'] : '', // "->" or "::"
            $frame['function'],
            $args
        );
        $count++;
    }
    return $rtn;
}

Alternatively, you could edit the php source where it is truncating the output: https://github.com/php/php-src/blob/master/Zend/zend_exceptions.c#L392

Solution 2

That solution is good but in my case it threw an error because my trace has internal functions in it. I added a few lines of code to check for that so the trace functions still works.

function getExceptionTraceAsString($exception) {
    $rtn = "";
    $count = 0;
    foreach ($exception->getTrace() as $frame) {


        $args = "";
        if (isset($frame['args'])) {
            $args = array();
            foreach ($frame['args'] as $arg) {
                if (is_string($arg)) {
                    $args[] = "'" . $arg . "'";
                } elseif (is_array($arg)) {
                    $args[] = "Array";
                } elseif (is_null($arg)) {
                    $args[] = 'NULL';
                } elseif (is_bool($arg)) {
                    $args[] = ($arg) ? "true" : "false";
                } elseif (is_object($arg)) {
                    $args[] = get_class($arg);
                } elseif (is_resource($arg)) {
                    $args[] = get_resource_type($arg);
                } else {
                    $args[] = $arg;
                }
            }
            $args = join(", ", $args);
        }
        $current_file = "[internal function]";
        if(isset($frame['file']))
        {
            $current_file = $frame['file'];
        }
        $current_line = "";
        if(isset($frame['line']))
        {
            $current_line = $frame['line'];
        }
        $rtn .= sprintf( "#%s %s(%s): %s(%s)\n",
            $count,
            $current_file,
            $current_line,
            $frame['function'],
            $args );
        $count++;
    }
    return $rtn;
}

Solution 3

Some better version https://stackoverflow.com/a/6076667/194508 is here https://gist.github.com/1437966 added class to output.

Solution 4

Will changing the php.ini setting log_errors_max_len help?

Also, please note that messages are truncated only during the output, you still can get the original error message with call to $exception->getMessage()

Solution 5

There is also the excellent jTraceEx recipe by Ernest Vogelsinger at https://www.php.net/manual/exception.gettraceasstring.php#114980, that supports chained exceptions and is formatted in a Java-like manner.

Here is a comparison taken directly from his comment on php.net :

Exception::getTraceAsString :

#0 /var/htdocs/websites/sbdevel/public/index.php(70): seabird\test\C->exc()
#1 /var/htdocs/websites/sbdevel/public/index.php(85): seabird\test\C->doexc()
#2 /var/htdocs/websites/sbdevel/public/index.php(89): seabird\test\fail2()
#3 /var/htdocs/websites/sbdevel/public/index.php(93): seabird\test\fail1()
#4 {main}

jTraceEx :

Exception: Thrown from class C
 at seabird.test.C.exc(index.php:78)
 at seabird.test.C.doexc(index.php:70)
 at seabird.test.fail2(index.php:85)
 at seabird.test.fail1(index.php:89)
 at (main)(index.php:93)
Caused by: Exception: Thrown from class B
 at seabird.test.B.exc(index.php:64)
 at seabird.test.C.exc(index.php:75)
 ... 4 more
Caused by: Exception: Thrown from class A
 at seabird.test.A.exc(index.php:46)
 at seabird.test.B.exc(index.php:61)
 ... 5 more
Share:
24,306
User
Author by

User

Updated on February 03, 2022

Comments

  • User
    User over 2 years

    I'm using getTraceAsString() to get a stack trace but the string is being truncated for some reason.

    Example, an exception is thrown and I log the string using:

    catch (SoapFault $e) {
    error_log( $e->getTraceAsString() )
    }
    

    The string thats prints out is:

    #0 C:\Somedirectory\Somedirectory\Somedirectory\Somedir\SomeScript.php(10): SoapClient->SoapClient('http://www.ex...')

    How can I get the full string to print?