Skip to content

Commit 2975508

Browse files
committed
Merge remote-tracking branch 'upstream/develop' into 4.5
2 parents 2c2b3cd + c96dc6d commit 2975508

File tree

13 files changed

+173
-61
lines changed

13 files changed

+173
-61
lines changed

system/Debug/ExceptionHandler.php

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ public function handle(
9999
. DIRECTORY_SEPARATOR . 'errors' . DIRECTORY_SEPARATOR . $addPath;
100100

101101
// Determine the views
102-
$view = $this->determineView($exception, $path);
103-
$altView = $this->determineView($exception, $altPath);
102+
$view = $this->determineView($exception, $path, $statusCode);
103+
$altView = $this->determineView($exception, $altPath, $statusCode);
104104

105105
// Check if the view exists
106106
$viewFile = null;
@@ -121,13 +121,16 @@ public function handle(
121121
}
122122

123123
/**
124-
* Determines the view to display based on the exception thrown,
125-
* whether an HTTP or CLI request, etc.
124+
* Determines the view to display based on the exception thrown, HTTP status
125+
* code, whether an HTTP or CLI request, etc.
126126
*
127127
* @return string The filename of the view file to use
128128
*/
129-
protected function determineView(Throwable $exception, string $templatePath): string
130-
{
129+
protected function determineView(
130+
Throwable $exception,
131+
string $templatePath,
132+
int $statusCode = 500
133+
): string {
131134
// Production environments should have a custom exception file.
132135
$view = 'production.php';
133136

@@ -149,8 +152,8 @@ protected function determineView(Throwable $exception, string $templatePath): st
149152
$templatePath = rtrim($templatePath, '\\/ ') . DIRECTORY_SEPARATOR;
150153

151154
// Allow for custom views based upon the status code
152-
if (is_file($templatePath . 'error_' . $exception->getCode() . '.php')) {
153-
return 'error_' . $exception->getCode() . '.php';
155+
if (is_file($templatePath . 'error_' . $statusCode . '.php')) {
156+
return 'error_' . $statusCode . '.php';
154157
}
155158

156159
return $view;

tests/system/Debug/ExceptionHandlerTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public function testDetermineViewsRuntimeExceptionCode404(): void
7171
$templatePath = APPPATH . 'Views/errors/html';
7272
$viewFile = $determineView($exception, $templatePath);
7373

74-
$this->assertSame('error_404.php', $viewFile);
74+
$this->assertSame('error_exception.php', $viewFile);
7575
}
7676

7777
public function testDetermineViewsDisplayErrorsOffRuntimeException(): void

user_guide_src/source/changelogs/v4.4.8.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ Release Date: Unreleased
1414
BREAKING
1515
********
1616

17+
- A bug that caused the :doc:`Exception handler <../general/errors>` to display
18+
incorrect error view file corresponding to the exception code has been fixed.
19+
The third parameter ``int $statusCode = 500`` has been added to
20+
``CodeIgniter\Debug\ExceptionHandler::determineView()`` for this purpose.
21+
1722
***************
1823
Message Changes
1924
***************

user_guide_src/source/database/metadata.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,14 @@ $db->getFieldNames()
5151
Returns an array containing the field names. This query can be called
5252
two ways:
5353

54-
1. You can supply the table name and call it from the ``$db->object``:
54+
1. You can supply the table name and call it from the ``$db`` object:
5555

56-
.. literalinclude:: metadata/003.php
56+
.. literalinclude:: metadata/003.php
5757

5858
2. You can gather the field names associated with any query you run by
59-
calling the function from your query result object:
59+
calling the function from your query result object:
6060

61-
.. literalinclude:: metadata/004.php
61+
.. literalinclude:: metadata/004.php
6262

6363
Determine If a Field is Present in a Table
6464
==========================================

user_guide_src/source/database/transactions.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@ Strict Mode can be disabled as follows:
6767
Managing Errors
6868
===============
6969

70-
When you have ``DBDebug`` true in your **app/Config/Database.php** file,
71-
if a query error occurs, all the queries will be rolled backed, and an exception
72-
will be thrown. So you'll see a standard error page.
70+
.. note::
71+
Since v4.3.0, during transactions, exceptions are not thrown by default
72+
even if ``DBDebug`` is true.
7373

74-
If the ``DBDebug`` is false, you can manage your own errors like this:
74+
You can manage your own errors like this:
7575

7676
.. literalinclude:: transactions/003.php
7777

user_guide_src/source/general/errors.rst

Lines changed: 81 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,29 @@ Using Exceptions
1919

2020
This section is a quick overview for newer programmers, or for developers who are not experienced with using exceptions.
2121

22+
What is Exceptions
23+
------------------
24+
2225
Exceptions are simply events that happen when the exception is "thrown". This halts the current flow of the script, and
2326
execution is then sent to the error handler which displays the appropriate error page:
2427

2528
.. literalinclude:: errors/001.php
2629

30+
Catching Exceptions
31+
-------------------
32+
2733
If you are calling a method that might throw an exception, you can catch that exception using a ``try/catch`` block:
2834

2935
.. literalinclude:: errors/002.php
3036

3137
If the ``$userModel`` throws an exception, it is caught and the code within the catch block is executed. In this example,
3238
the scripts dies, echoing the error message that the ``UserModel`` defined.
3339

40+
Catching Specific Exceptions
41+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
42+
3443
In the example above, we catch any type of Exception. If we only want to watch for specific types of exceptions, like
35-
a ``UnknownFileException``, we can specify that in the catch parameter. Any other exceptions that are thrown and are
44+
a ``DataException``, we can specify that in the catch parameter. Any other exceptions that are thrown and are
3645
not child classes of the caught exception will be passed on to the error handler:
3746

3847
.. literalinclude:: errors/003.php
@@ -65,7 +74,7 @@ See :ref:`setting-environment`.
6574
Logging Exceptions
6675
------------------
6776

68-
By default, all Exceptions other than 404 - Page Not Found exceptions are logged. This can be turned on and off
77+
By default, all Exceptions other than "404 - Page Not Found" exceptions are logged. This can be turned on and off
6978
by setting the ``$log`` value of **app/Config/Exceptions.php**:
7079

7180
.. literalinclude:: errors/005.php
@@ -74,8 +83,40 @@ To ignore logging on other status codes, you can set the status code to ignore i
7483

7584
.. literalinclude:: errors/006.php
7685

77-
.. note:: It is possible that logging still will not happen for exceptions if your current Log settings
78-
are not set up to log **critical** errors, which all exceptions are logged as.
86+
.. note:: It is possible that logging still will not happen for exceptions if your current
87+
:ref:`Log settings <logging-configuration>`
88+
are not set up to log ``critical`` errors, which all exceptions are logged as.
89+
90+
.. _logging_deprecation_warnings:
91+
92+
Logging Deprecation Warnings
93+
----------------------------
94+
95+
.. versionadded:: 4.3.0
96+
97+
By default, all errors reported by ``error_reporting()`` will be thrown as an ``ErrorException`` object. These
98+
include both ``E_DEPRECATED`` and ``E_USER_DEPRECATED`` errors. With the surge in use of PHP 8.1+, many users
99+
may see exceptions thrown for `passing null to non-nullable arguments of internal functions <https://wiki.php.net/rfc/deprecate_null_to_scalar_internal_arg>`_.
100+
To ease the migration to PHP 8.1, you can instruct CodeIgniter to log the deprecations instead of throwing them.
101+
102+
First, make sure your copy of ``Config\Exceptions`` is updated with the two new properties and set as follows:
103+
104+
.. literalinclude:: errors/012.php
105+
106+
Next, depending on the log level you set in ``Config\Exceptions::$deprecationLogLevel``, check whether the
107+
logger threshold defined in ``Config\Logger::$threshold`` covers the deprecation log level. If not, adjust
108+
it accordingly.
109+
110+
.. literalinclude:: errors/013.php
111+
112+
After that, subsequent deprecations will be logged instead of thrown.
113+
114+
This feature also works with user deprecations:
115+
116+
.. literalinclude:: errors/014.php
117+
118+
For testing your application you may want to always throw on deprecations. You may configure this by
119+
setting the environment variable ``CODEIGNITER_SCREAM_DEPRECATIONS`` to a truthy value.
79120

80121
Framework Exceptions
81122
====================
@@ -85,15 +126,17 @@ The following framework exceptions are available:
85126
PageNotFoundException
86127
---------------------
87128

88-
This is used to signal a 404, Page Not Found error. When thrown, the system will show the view found at
89-
**app/Views/errors/html/error_404.php**. You should customize all of the error views for your site.
90-
If, in **app/Config/Routes.php**, you have specified a 404 Override, that will be called instead of the standard
91-
404 page:
129+
This is used to signal a 404, Page Not Found error:
92130

93131
.. literalinclude:: errors/007.php
94132

95133
You can pass a message into the exception that will be displayed in place of the default message on the 404 page.
96134

135+
For the default 404 view file location, see :ref:`http-status-code-and-error-views`.
136+
137+
If, in **app/Config/Routing.php** or **app/Config/Routes.php**, you have specified
138+
a :ref:`404-override`, that will be called instead of the standard 404 page.
139+
97140
ConfigException
98141
---------------
99142

@@ -144,52 +187,52 @@ Specify HTTP Status Code in Your Exception
144187
.. versionadded:: 4.3.0
145188

146189
Since v4.3.0, you can specify the HTTP status code for your Exception class to implement
147-
``HTTPExceptionInterface``.
190+
``CodeIgniter\Exceptions\HTTPExceptionInterface``.
148191

149192
When an exception implementing ``HTTPExceptionInterface`` is caught by CodeIgniter's exception handler, the Exception code will become the HTTP status code.
150193

151-
.. _error-specify-exit-code:
194+
.. _http-status-code-and-error-views:
152195

153-
Specify Exit Code in Your Exception
154-
===================================
196+
HTTP Status Code and Error Views
197+
================================
155198

156-
.. versionadded:: 4.3.0
199+
The exception handler displays the error view corresponding to the HTTP status
200+
code, if one exists.
157201

158-
Since v4.3.0, you can specify the exit code for your Exception class to implement
159-
``HasExitCodeInterface``.
160-
161-
When an exception implementing ``HasExitCodeInterface`` is caught by CodeIgniter's exception handler, the code returned from the ``getExitCode()`` method will become the exit code.
202+
For example, ``PageNotFoundException`` implements the ``HTTPExceptionInterface``,
203+
so its exception code ``404`` will be the HTTP status code. Therefore if it is
204+
thrown, the system will show the **error_404.php** in the **app/Views/errors/html**
205+
folder when it is a web request. If it is invoked via CLI, the system will show
206+
the **error_404.php** in the **app/Views/errors/cli** folder.
162207

163-
.. _logging_deprecation_warnings:
208+
If there is no view file corresponding to the HTTP status code, **production.php**
209+
or **error_exception.php** will be displayed.
164210

165-
Logging Deprecation Warnings
166-
============================
167-
168-
.. versionadded:: 4.3.0
169-
170-
By default, all errors reported by ``error_reporting()`` will be thrown as an ``ErrorException`` object. These
171-
include both ``E_DEPRECATED`` and ``E_USER_DEPRECATED`` errors. With the surge in use of PHP 8.1+, many users
172-
may see exceptions thrown for `passing null to non-nullable arguments of internal functions <https://wiki.php.net/rfc/deprecate_null_to_scalar_internal_arg>`_.
173-
To ease the migration to PHP 8.1, you can instruct CodeIgniter to log the deprecations instead of throwing them.
211+
.. note:: If ``display_errors`` is on in the PHP INI configuration,
212+
**error_exception.php** is selected and a detailed error report is displayed.
174213

175-
First, make sure your copy of ``Config\Exceptions`` is updated with the two new properties and set as follows:
214+
You should customize all of the error views in the **app/Views/errors/html** folder
215+
for your site.
176216

177-
.. literalinclude:: errors/012.php
217+
You can also create error views for specific HTTP status code. For example, if
218+
you want to create an error view for "400 Bad Request", add **error_400.php**.
178219

179-
Next, depending on the log level you set in ``Config\Exceptions::$deprecationLogLevel``, check whether the
180-
logger threshold defined in ``Config\Logger::$threshold`` covers the deprecation log level. If not, adjust
181-
it accordingly.
220+
.. warning:: If an error view file with the corresponding HTTP status code exists,
221+
the exception handler will display that file regardless of the environment.
222+
The view file must be implemented in such a way that it does not display
223+
detailed error messages in production environment by yourself.
182224

183-
.. literalinclude:: errors/013.php
225+
.. _error-specify-exit-code:
184226

185-
After that, subsequent deprecations will be logged instead of thrown.
227+
Specify Exit Code in Your Exception
228+
===================================
186229

187-
This feature also works with user deprecations:
230+
.. versionadded:: 4.3.0
188231

189-
.. literalinclude:: errors/014.php
232+
Since v4.3.0, you can specify the exit code for your Exception class to implement
233+
``CodeIgniter\Exceptions\HasExitCodeInterface``.
190234

191-
For testing your application you may want to always throw on deprecations. You may configure this by
192-
setting the environment variable ``CODEIGNITER_SCREAM_DEPRECATIONS`` to a truthy value.
235+
When an exception implementing ``HasExitCodeInterface`` is caught by CodeIgniter's exception handler, the code returned from the ``getExitCode()`` method will become the exit code.
193236

194237
.. _custom-exception-handlers:
195238

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
<?php
22

3+
use CodeIgniter\Database\Exceptions\DataException;
4+
35
try {
46
$user = $userModel->find($id);
5-
} catch (\CodeIgniter\UnknownFileException $e) {
7+
} catch (DataException $e) {
68
// do something here...
79
}

user_guide_src/source/general/errors/004.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
<?php
22

3+
use CodeIgniter\Database\Exceptions\DataException;
4+
35
try {
46
$user = $userModel->find($id);
5-
} catch (\CodeIgniter\UnknownFileException $e) {
7+
} catch (DataException $e) {
68
// do something here...
79

810
throw new \RuntimeException($e->getMessage(), $e->getCode(), $e);

user_guide_src/source/general/errors/005.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,7 @@
66

77
class Exceptions extends BaseConfig
88
{
9-
public $log = true;
9+
// ...
10+
public bool $log = true;
11+
// ...
1012
}

user_guide_src/source/general/errors/006.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,7 @@
66

77
class Exceptions extends BaseConfig
88
{
9-
public $ignoredCodes = [404];
9+
// ...
10+
public array $ignoreCodes = [404];
11+
// ...
1012
}

0 commit comments

Comments
 (0)