Failed Conditions
Push — newinternal ( 216d62...410e59 )
by Simon
05:28 queued 13s
created

ExceptionHandler   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 109
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 7
eloc 40
c 1
b 0
f 0
dl 0
loc 109
ccs 0
cts 63
cp 0
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A getExceptionData() 0 11 2
A exceptionHandler() 0 65 4
A errorHandler() 0 4 1
1
<?php
2
/******************************************************************************
3
 * Wikipedia Account Creation Assistance tool                                 *
4
 *                                                                            *
5
 * All code in this file is released into the public domain by the ACC        *
6
 * Development Team. Please see team.json for a list of contributors.         *
7
 ******************************************************************************/
8
9
namespace Waca;
10
11
use ErrorException;
12
use Exception;
13
14
class ExceptionHandler
15
{
16
    /**
17
     * Global exception handler
18
     *
19
     * Smarty would be nice to use, but it COULD BE smarty that throws the errors.
20
     * Let's build something ourselves, and hope it works.
21
     *
22
     * @param $exception
23
     *
24
     * @category Security-Critical - has the potential to leak data when exception is thrown.
25
     */
26
    public static function exceptionHandler(Exception $exception)
27
    {
28
        /** @global $siteConfiguration SiteConfiguration */
29
        global $siteConfiguration;
30
31
        $errorDocument = <<<HTML
32
<!DOCTYPE html>
33
<html lang="en"><head>
34
<meta charset="utf-8">
35
<title>Oops! Something went wrong!</title>
36
<meta name="viewport" content="width=device-width, initial-scale=1.0">
37
<link href="{$siteConfiguration->getBaseUrl()}/lib/bootstrap/css/bootstrap.min.css" rel="stylesheet">
38
<style>
39
  body {
40
    padding-top: 60px;
41
  }
42
</style>
43
<link href="{$siteConfiguration->getBaseUrl()}/lib/bootstrap/css/bootstrap-responsive.min.css" rel="stylesheet">
44
</head><body><div class="container">
45
<h1>Oops! Something went wrong!</h1>
46
<p>We'll work on fixing this for you, so why not come back later?</p>
47
<p class="muted">If our trained monkeys ask, tell them this error ID: <code>$1$</code></p>
48
$2$
49
</div></body></html>
50
HTML;
51
52
        $errorData = self::getExceptionData($exception);
53
        $errorData['server'] = $_SERVER;
54
        $errorData['get'] = $_GET;
55
        $errorData['post'] = $_POST;
56
57
        $state = serialize($errorData);
58
        $errorId = sha1($state);
59
60
        // Save the error for later analysis
61
        file_put_contents($siteConfiguration->getErrorLog() . '/' . $errorId . '.log', $state);
62
63
        // clear and discard any content that's been saved to the output buffer
64
        if (ob_get_level() > 0) {
65
            ob_end_clean();
66
        }
67
68
        // push error ID into the document.
69
        $message = str_replace('$1$', $errorId, $errorDocument);
70
71
        if ($siteConfiguration->getDebuggingTraceEnabled()) {
72
            ob_start();
73
            var_dump($errorData);
1 ignored issue
show
Security Debugging Code introduced by
var_dump($errorData) looks like debug code. Are you sure you do not want to remove it?
Loading history...
74
            $textErrorData = ob_get_contents();
75
            ob_end_clean();
76
77
            $message = str_replace('$2$', $textErrorData, $message);
78
        }
79
        else {
80
            $message = str_replace('$2$', "", $message);
81
        }
82
83
        // While we *shouldn't* have sent headers by now due to the output buffering, PHPUnit does weird things.
84
        // This is "only" needed for the tests, but it's a good idea to wrap this anyway.
85
        if (!headers_sent()) {
86
            header('HTTP/1.1 500 Internal Server Error');
87
        }
88
89
        // output the document
90
        print $message;
91
    }
92
93
    /**
94
     * @param int    $errorSeverity The severity level of the exception.
95
     * @param string $errorMessage  The Exception message to throw.
96
     * @param string $errorFile     The filename where the exception is thrown.
97
     * @param int    $errorLine     The line number where the exception is thrown.
98
     *
99
     * @throws ErrorException
100
     */
101
    public static function errorHandler($errorSeverity, $errorMessage, $errorFile, $errorLine)
102
    {
103
        // call into the main exception handler above
104
        throw new ErrorException($errorMessage, 0, $errorSeverity, $errorFile, $errorLine);
105
    }
106
107
    /**
108
     * @param Exception $exception
109
     *
110
     * @return null|array
111
     */
112
    public static function getExceptionData($exception)
113
    {
114
        if ($exception == null) {
115
            return null;
116
        }
117
118
        return array(
119
            'exception' => get_class($exception),
120
            'message'   => $exception->getMessage(),
121
            'stack'     => $exception->getTraceAsString(),
122
            'previous'  => self::getExceptionData($exception->getPrevious()),
123
        );
124
    }
125
}