Completed
Push — master ( bd5ff6...90c2c7 )
by Bernhard
07:04
created

ExceptionTrace::printTrace()   C

Complexity

Conditions 10
Paths 148

Size

Total Lines 56
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 10.0034

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 56
ccs 30
cts 31
cp 0.9677
rs 6.281
cc 10
eloc 34
nc 148
nop 2
crap 10.0034

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * This file is part of the webmozart/console package.
5
 *
6
 * (c) Bernhard Schussek <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Webmozart\Console\UI\Component;
13
14
use Exception;
15
use Webmozart\Console\Api\IO\IO;
16
use Webmozart\Console\UI\Component;
17
18
/**
19
 * Renders the trace of an exception.
20
 *
21
 * @since  1.0
22
 *
23
 * @author Bernhard Schussek <[email protected]>
24
 */
25
class ExceptionTrace implements Component
26
{
27
    /**
28
     * @var Exception
29
     */
30
    private $exception;
31
32
    /**
33
     * Creates a renderer for the given exception.
34
     *
35
     * @param Exception $exception The exception to render.
36
     */
37 6
    public function __construct(Exception $exception)
38
    {
39 6
        $this->exception = $exception;
40 6
    }
41
42
    /**
43
     * Renders the exception trace.
44
     *
45
     * @param IO  $io          The I/O.
46
     * @param int $indentation The number of spaces to indent.
47
     */
48 6
    public function render(IO $io, $indentation = 0)
49
    {
50 6
        if (!$io->isVerbose()) {
51 4
            $io->errorLine('fatal: '.$this->exception->getMessage());
52
53 4
            return;
54
        }
55
56 2
        $exception = $this->exception;
57
58 2
        $this->renderException($io, $exception);
59
60 2
        if ($io->isVeryVerbose()) {
61 1
            while ($exception = $exception->getPrevious()) {
62 1
                $io->errorLine('Caused by:');
63
64 1
                $this->renderException($io, $exception);
65
            }
66
        }
67 2
    }
68
69 2
    private function renderException(IO $io, Exception $exception)
70
    {
71 2
        $this->printBox($io, $exception);
72 2
        $this->printTrace($io, $exception);
73 2
    }
74
75 2
    private function printBox(IO $io, Exception $exception)
76
    {
77 2
        $screenWidth = $io->getTerminalDimensions()->getWidth() - 1;
78 2
        $boxWidth = 0;
79
80 2
        $boxLines = array_merge(
81 2
            array(sprintf('[%s]', get_class($exception))),
82
            // TODO replace by implementation that is aware of format codes
83 2
            explode("\n", wordwrap($exception->getMessage(), $screenWidth - 4))
84
        );
85
86 2
        foreach ($boxLines as $line) {
87 2
            $boxWidth = max($boxWidth, strlen($line));
88
        }
89
90
        // TODO handle $boxWidth > $screenWidth
91 2
        $emptyLine = sprintf('<error>%s</error>', str_repeat(' ', $boxWidth + 4));
92
93 2
        $io->errorLine('');
94 2
        $io->errorLine('');
95 2
        $io->errorLine($emptyLine);
96
97 2
        foreach ($boxLines as $boxLine) {
98 2
            $padding = str_repeat(' ', max(0, $boxWidth - strlen($boxLine)));
99 2
            $io->errorLine(sprintf('<error>  %s%s  </error>', $boxLine, $padding));
100
        }
101
102 2
        $io->errorLine($emptyLine);
103 2
        $io->errorLine('');
104 2
        $io->errorLine('');
105 2
    }
106
107 2
    private function printTrace(IO $io, Exception $exception)
108
    {
109 2
        $traces = $exception->getTrace();
110 2
        $cwd = getcwd().DIRECTORY_SEPARATOR;
111 2
        $cwdLength = strlen($cwd);
112
113
        $lastTrace = array(
114 2
            'function' => '',
115
            'args' => array(),
116
        );
117
118 2
        if (null !== $exception->getFile()) {
119 2
            $lastTrace['file'] = $exception->getFile();
120
        }
121
122 2
        if (null !== $exception->getLine()) {
123 2
            $lastTrace['line'] = $exception->getLine();
124
        }
125
126 2
        array_unshift($traces, $lastTrace);
127
128 2
        $io->errorLine('<b>Exception trace:</b>');
129
130 2
        foreach ($traces as $trace) {
131 2
            $namespace = '';
132 2
            $class = '';
133 2
            $location = 'n/a';
134
135 2
            if (isset($trace['class'])) {
136 2
                if (false !== $pos = strrpos($trace['class'], '\\')) {
137 2
                    $namespace = substr($trace['class'], 0, $pos + 1);
138 2
                    $class = substr($trace['class'], $pos + 1);
139
                } else {
140 2
                    $class = $trace['class'];
141
                }
142
            }
143
144 2
            if (isset($trace['file'])) {
145 2
                if (0 === strpos($trace['file'], $cwd)) {
146 2
                    $location = substr($trace['file'], $cwdLength);
147
                } else {
148
                    $location = $trace['file'];
149
                }
150
            }
151
152
            // class, operator, function
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
153 2
            $signature = $class.(isset($trace['type']) ? $trace['type'] : '').$trace['function'];
154 2
            $location .= ':'.(isset($trace['line']) ? $trace['line'] : 'n/a');
155
156 2
            $io->errorLineRaw(sprintf('  %s%s()', $namespace, $io->format('<u>'.$signature.'</u>')));
157 2
            $io->errorLineRaw(sprintf('    %s', $io->format('<c1>'.$location.'</c1>')));
158
        }
159
160 2
        $io->errorLine('');
161 2
        $io->errorLine('');
162 2
    }
163
}
164