public static function generateCallTrace(\Throwable $e = null): string
    {
        ob_start();
        if (null === $e) {
            $e = new \Exception();
            $trace = explode("\n", $e->getTraceAsString());
            $args = array_reverse($e->getTrace());
            $trace = array_reverse($trace);
            array_shift($trace); // remove {main}
            array_pop($args); // remove call to this method
            array_pop($args); // remove call to this method
            array_pop($trace); // remove call to this method
            array_pop($trace); // remove call to this method
        } else {
            $trace = explode("\n", $e->getTraceAsString());
            $args = array_reverse($e->getTrace());
            $trace = array_reverse($trace);
            array_shift($trace); // remove {main}
        }


        $length = \count($trace);
        $result = array();
        for ($i = 0; $i < $length; $i++) {
            $result[] = ($i + 1) . ') ' . implode(' (', explode('(', substr($trace[$i], strpos($trace[$i], ' ')))) . PHP_EOL . "\t\t\t\t" . json_encode($args[$i]['args']) . PHP_EOL;
        }
        print "\n\t" . implode("\n\t", $result);

        $output = ob_get_contents();
        ob_end_clean();
        return $output;
    }