Passed
Push — master ( 6015fa...83e3bb )
by Tom
02:48
created

ExceptionHandler::handle()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 9
ccs 5
cts 5
cp 1
crap 2
rs 9.6666
c 0
b 0
f 0
1
<?php
2
3
/* this file is part of pipelines */
4
5
namespace Ktomk\Pipelines\Utility;
6
7
use Exception;
8
use Ktomk\Pipelines\Cli\ArgsException;
9
use Ktomk\Pipelines\Cli\Streams;
10
use Ktomk\Pipelines\File\ParseException;
11
12
class ExceptionHandler
13
{
14
    /**
15
     * @var bool
16
     */
17
    private $showStacktrace = false;
18
19
    /**
20
     * @var Help
21
     */
22
    private $help;
23
    /**
24
     * @var Streams
25
     */
26
    private $streams;
27
28
    /**
29
     * ExceptionHandler constructor.
30
     * @param Streams $streams
31
     * @param Help $help
32
     * @param bool $showStacktrace
33
     */
34 1
    public function __construct(Streams $streams, Help $help, $showStacktrace)
35
    {
36 1
        $this->streams = $streams;
37 1
        $this->help = $help;
38 1
        $this->showStacktrace = $showStacktrace;
39 1
    }
40
41
    /**
42
     * @param Runnable $runnable
43
     * @return mixed|void
44
     */
45 3
    public function handle(Runnable $runnable)
46
    {
47
        try {
48 3
            $status = $runnable->run();
49 2
        } catch (Exception $e) {
50 2
            $status = $this->handleException($e);
51
        }
52
53 3
        return $status;
54
    }
55
56
    /**
57
     * @param Exception $e
58
     * @return int
59
     */
60 2
    private function handleException(Exception $e)
61
    {
62 2
        $status = $e->getCode();
63 2
        $message = $e->getMessage();
64
65 2
        if ($this->isUnexpectedException($e)) {
66
            // catch unexpected exceptions for user-friendly message
67 1
            $status = 2;
68 1
            $message = sprintf('fatal: %s', $e->getMessage());
69
        }
70
71 2
        if (0 !== $status && '' !== $message) {
72 2
            $this->error(sprintf('pipelines: %s', $message));
73
        }
74
75 2
        if ($e instanceof ArgsException) {
76 1
            $this->help->showUsage();
77
        }
78
79 2
        if ($this->showStacktrace) {
80 2
            $this->debugException($e);
81
        }
82
83 2
        return $status;
84
    }
85
86 2
    private function isUnexpectedException(Exception $e)
87
    {
88
        return (
89 2
            !($e instanceof ArgsException)
90 2
            && !($e instanceof StatusException)
91 2
            && !($e instanceof ParseException)
92
        );
93
    }
94
95 2
    private function debugException(Exception $e)
96
    {
97 2
        for (; $e; $e = $e->getPrevious()) {
98 2
            $this->error('--------');
99 2
            $this->error(sprintf("class....: %s", get_class($e)));
100 2
            $this->error(sprintf("message..: %s", $e->getMessage()));
101 2
            $this->error(sprintf("code.....: %s", $e->getCode()));
102 2
            $this->error(sprintf("file.....: %s", $e->getFile()));
103 2
            $this->error(sprintf("line.....: %s", $e->getLine()));
104 2
            $this->error('backtrace:');
105 2
            $this->error($e->getTraceAsString());
106
        }
107 2
        $this->error('--------');
108 2
    }
109
110 2
    private function error($message)
111
    {
112 2
        $this->streams->err(
113 2
            sprintf("%s\n", $message)
114
        );
115 2
    }
116
}
117