Passed
Push — master ( 093846...a50b30 )
by 世昌
05:11 queued 10s
created

ExceptionCatcher::dumpThrowable()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 15
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 18
rs 9.7666
1
<?php
2
3
namespace suda\application\debug;
4
5
use Throwable;
6
use Exception;
7
use suda\framework\Context;
8
use suda\framework\debug\DebugObject;
9
use suda\application\ApplicationContext;
10
use suda\framework\filesystem\FileSystem;
11
12
class ExceptionCatcher
13
{
14
    /**
15
     * 应用
16
     *
17
     * @var ApplicationContext
18
     */
19
    protected $applicationContext;
20
21
    /**
22
     * @var array
23
     */
24
    protected $context;
25
26
    /**
27
     * @var callable
28
     */
29
    protected $last;
30
31
    /**
32
     * ExceptionCatcher constructor.
33
     * @param ApplicationContext $application
34
     * @param array $context
35
     */
36
    public function __construct(ApplicationContext $application, array $context = [])
37
    {
38
        $this->applicationContext = $application;
39
        $this->context = $context;
40
    }
41
42
    /**
43
     * 注册错误处理函数
44
     * @return self
45
     */
46
    public function register()
47
    {
48
        $this->last = set_exception_handler([$this, 'uncaughtException']);
49
        return $this;
50
    }
51
52
    /**
53
     * 重置监控工具
54
     */
55
    public function restore() {
56
        restore_exception_handler();
57
        if ($this->last !== null) {
58
            set_exception_handler($this->last);
59
        }
60
    }
61
62
    /**
63
     * 异常托管
64
     *
65
     * @param Throwable $exception
66
     * @return void
67
     * @throws Exception
68
     */
69
    public function uncaughtException($exception)
70
    {
71
        $this->applicationContext->debug()->addIgnorePath(__FILE__);
72
        $this->applicationContext->debug()->uncaughtException($exception);
73
        $this->dumpThrowable($exception);
74
    }
75
76
    /**
77
     * @param Throwable $throwable
78
     */
79
    public function dumpThrowable($throwable)
80
    {
81
        $dumpPath = $this->applicationContext->conf('save-dump-path');
82
        if ($dumpPath !== null) {
83
            $this->context['application'] = $this->applicationContext;
84
            $dumper = [
85
                'time' => time(),
86
                'throwable' => $throwable,
87
                'context' => $this->context,
88
                'backtrace' => $throwable->getTrace(),
89
            ];
90
            $exceptionHash = md5($throwable->getFile() . $throwable->getLine() . $throwable->getCode());
91
            $path = $dumpPath . '/' . microtime(true) . '.' . substr($exceptionHash, 0, 8) . '.json';
92
            FileSystem::make($dumpPath);
93
            FileSystem::put($path, json_encode(
94
                new DebugObject($dumper),
95
                JSON_PRETTY_PRINT
96
                | JSON_UNESCAPED_UNICODE
97
            ));
98
        }
99
    }
100
}