• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

codeigniter4 / CodeIgniter4 / 8677009716

13 Apr 2024 11:45PM UTC coverage: 84.44% (-2.2%) from 86.607%
8677009716

push

github

web-flow
Merge pull request #8776 from kenjis/fix-findQualifiedNameFromPath-Cannot-declare-class-v3

fix: Cannot declare class CodeIgniter\Config\Services, because the name is already in use

0 of 3 new or added lines in 1 file covered. (0.0%)

478 existing lines in 72 files now uncovered.

20318 of 24062 relevant lines covered (84.44%)

188.23 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.02
/system/Debug/ExceptionHandler.php
1
<?php
2

3
declare(strict_types=1);
4

5
/**
6
 * This file is part of CodeIgniter 4 framework.
7
 *
8
 * (c) CodeIgniter Foundation <admin@codeigniter.com>
9
 *
10
 * For the full copyright and license information, please view
11
 * the LICENSE file that was distributed with this source code.
12
 */
13

14
namespace CodeIgniter\Debug;
15

16
use CodeIgniter\API\ResponseTrait;
17
use CodeIgniter\Exceptions\PageNotFoundException;
18
use CodeIgniter\HTTP\Exceptions\HTTPException;
19
use CodeIgniter\HTTP\IncomingRequest;
20
use CodeIgniter\HTTP\RequestInterface;
21
use CodeIgniter\HTTP\ResponseInterface;
22
use Config\Paths;
23
use Throwable;
24

25
/**
26
 * @see \CodeIgniter\Debug\ExceptionHandlerTest
27
 */
28
final class ExceptionHandler extends BaseExceptionHandler implements ExceptionHandlerInterface
29
{
30
    use ResponseTrait;
31

32
    /**
33
     * ResponseTrait needs this.
34
     */
35
    private ?RequestInterface $request = null;
36

37
    /**
38
     * ResponseTrait needs this.
39
     */
40
    private ?ResponseInterface $response = null;
41

42
    /**
43
     * Determines the correct way to display the error.
44
     */
45
    public function handle(
46
        Throwable $exception,
47
        RequestInterface $request,
48
        ResponseInterface $response,
49
        int $statusCode,
50
        int $exitCode
51
    ): void {
52
        // ResponseTrait needs these properties.
53
        $this->request  = $request;
3✔
54
        $this->response = $response;
3✔
55

56
        if ($request instanceof IncomingRequest) {
3✔
57
            try {
58
                $response->setStatusCode($statusCode);
2✔
59
            } catch (HTTPException) {
×
60
                // Workaround for invalid HTTP status code.
61
                $statusCode = 500;
×
62
                $response->setStatusCode($statusCode);
×
63
            }
64

65
            if (! headers_sent()) {
2✔
66
                header(
2✔
67
                    sprintf(
2✔
68
                        'HTTP/%s %s %s',
2✔
69
                        $request->getProtocolVersion(),
2✔
70
                        $response->getStatusCode(),
2✔
71
                        $response->getReasonPhrase()
2✔
72
                    ),
2✔
73
                    true,
2✔
74
                    $statusCode
2✔
75
                );
2✔
76
            }
77

78
            if (! str_contains($request->getHeaderLine('accept'), 'text/html')) {
2✔
79
                $data = (ENVIRONMENT === 'development' || ENVIRONMENT === 'testing')
1✔
80
                    ? $this->collectVars($exception, $statusCode)
1✔
81
                    : '';
×
82

83
                $this->respond($data, $statusCode)->send();
1✔
84

85
                if (ENVIRONMENT !== 'testing') {
1✔
86
                    // @codeCoverageIgnoreStart
UNCOV
87
                    exit($exitCode);
×
88
                    // @codeCoverageIgnoreEnd
89
                }
90

91
                return;
1✔
92
            }
93
        }
94

95
        // Determine possible directories of error views
96
        $addPath = ($request instanceof IncomingRequest ? 'html' : 'cli') . DIRECTORY_SEPARATOR;
2✔
97
        $path    = $this->viewPath . $addPath;
2✔
98
        $altPath = rtrim((new Paths())->viewDirectory, '\\/ ')
2✔
99
            . DIRECTORY_SEPARATOR . 'errors' . DIRECTORY_SEPARATOR . $addPath;
2✔
100

101
        // Determine the views
102
        $view    = $this->determineView($exception, $path, $statusCode);
2✔
103
        $altView = $this->determineView($exception, $altPath, $statusCode);
2✔
104

105
        // Check if the view exists
106
        $viewFile = null;
2✔
107
        if (is_file($path . $view)) {
2✔
108
            $viewFile = $path . $view;
2✔
109
        } elseif (is_file($altPath . $altView)) {
×
110
            $viewFile = $altPath . $altView;
×
111
        }
112

113
        // Displays the HTML or CLI error code.
114
        $this->render($exception, $statusCode, $viewFile);
2✔
115

116
        if (ENVIRONMENT !== 'testing') {
2✔
117
            // @codeCoverageIgnoreStart
UNCOV
118
            exit($exitCode);
×
119
            // @codeCoverageIgnoreEnd
120
        }
121
    }
122

123
    /**
124
     * Determines the view to display based on the exception thrown, HTTP status
125
     * code, whether an HTTP or CLI request, etc.
126
     *
127
     * @return string The filename of the view file to use
128
     */
129
    protected function determineView(
130
        Throwable $exception,
131
        string $templatePath,
132
        int $statusCode = 500
133
    ): string {
134
        // Production environments should have a custom exception file.
135
        $view = 'production.php';
6✔
136

137
        if (
138
            in_array(
6✔
139
                strtolower(ini_get('display_errors')),
6✔
140
                ['1', 'true', 'on', 'yes'],
6✔
141
                true
6✔
142
            )
6✔
143
        ) {
144
            $view = 'error_exception.php';
5✔
145
        }
146

147
        // 404 Errors
148
        if ($exception instanceof PageNotFoundException) {
6✔
149
            return 'error_404.php';
3✔
150
        }
151

152
        $templatePath = rtrim($templatePath, '\\/ ') . DIRECTORY_SEPARATOR;
3✔
153

154
        // Allow for custom views based upon the status code
155
        if (is_file($templatePath . 'error_' . $statusCode . '.php')) {
3✔
156
            return 'error_' . $statusCode . '.php';
×
157
        }
158

159
        return $view;
3✔
160
    }
161
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc