Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Open sidebar
project
drupal
Commits
51a27d10
Commit
51a27d10
authored
Sep 15, 2014
by
alexpott
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue
#2323759
by Crell, dawehner: Modularize kernel exception handling.
parent
983cdbf0
Changes
22
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
1328 additions
and
568 deletions
+1328
-568
core/core.services.yml
core/core.services.yml
+41
-8
core/includes/menu.inc
core/includes/menu.inc
+1
-1
core/lib/Drupal/Core/ContentNegotiation.php
core/lib/Drupal/Core/ContentNegotiation.php
+1
-1
core/lib/Drupal/Core/Controller/ExceptionController.php
core/lib/Drupal/Core/Controller/ExceptionController.php
+0
-452
core/lib/Drupal/Core/EventSubscriber/AuthenticationSubscriber.php
.../Drupal/Core/EventSubscriber/AuthenticationSubscriber.php
+2
-2
core/lib/Drupal/Core/EventSubscriber/CustomPageExceptionHtmlSubscriber.php
...ore/EventSubscriber/CustomPageExceptionHtmlSubscriber.php
+149
-0
core/lib/Drupal/Core/EventSubscriber/DefaultExceptionHtmlSubscriber.php
...l/Core/EventSubscriber/DefaultExceptionHtmlSubscriber.php
+121
-0
core/lib/Drupal/Core/EventSubscriber/DefaultExceptionSubscriber.php
...rupal/Core/EventSubscriber/DefaultExceptionSubscriber.php
+276
-0
core/lib/Drupal/Core/EventSubscriber/ExceptionJsonSubscriber.php
...b/Drupal/Core/EventSubscriber/ExceptionJsonSubscriber.php
+68
-0
core/lib/Drupal/Core/EventSubscriber/ExceptionListener.php
core/lib/Drupal/Core/EventSubscriber/ExceptionListener.php
+0
-36
core/lib/Drupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php
...rupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php
+113
-0
core/lib/Drupal/Core/EventSubscriber/ExceptionTestSiteSubscriber.php
...upal/Core/EventSubscriber/ExceptionTestSiteSubscriber.php
+67
-0
core/lib/Drupal/Core/EventSubscriber/Fast404ExceptionHtmlSubscriber.php
...l/Core/EventSubscriber/Fast404ExceptionHtmlSubscriber.php
+89
-0
core/lib/Drupal/Core/EventSubscriber/HttpExceptionSubscriberBase.php
...upal/Core/EventSubscriber/HttpExceptionSubscriberBase.php
+129
-0
core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php
...Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php
+1
-0
core/lib/Drupal/Core/Routing/Enhancer/ParamConversionEnhancer.php
.../Drupal/Core/Routing/Enhancer/ParamConversionEnhancer.php
+1
-1
core/lib/Drupal/Core/Utility/Error.php
core/lib/Drupal/Core/Utility/Error.php
+2
-1
core/modules/shortcut/shortcut.module
core/modules/shortcut/shortcut.module
+2
-8
core/modules/simpletest/src/WebTestBase.php
core/modules/simpletest/src/WebTestBase.php
+4
-0
core/modules/system/src/Tests/Routing/ExceptionHandlingTest.php
...odules/system/src/Tests/Routing/ExceptionHandlingTest.php
+120
-0
core/tests/Drupal/Tests/Core/Controller/ExceptionControllerTest.php
.../Drupal/Tests/Core/Controller/ExceptionControllerTest.php
+0
-58
core/tests/Drupal/Tests/Core/EventSubscriber/CustomPageExceptionHtmlSubscriberTest.php
...EventSubscriber/CustomPageExceptionHtmlSubscriberTest.php
+141
-0
No files found.
core/core.services.yml
View file @
51a27d10
...
...
@@ -196,6 +196,11 @@ services:
factory_method
:
get
factory_service
:
logger.factory
arguments
:
[
'
system'
]
logger.channel.php
:
class
:
Drupal\Core\Logger\LoggerChannel
factory_method
:
get
factory_service
:
logger.factory
arguments
:
[
'
php'
]
logger.channel.image
:
class
:
Drupal\Core\Logger\LoggerChannel
factory_method
:
get
...
...
@@ -736,16 +741,44 @@ services:
tags
:
-
{
name
:
event_subscriber
}
arguments
:
[
'
@config.manager'
,
'
@config.storage'
,
'
@config.storage.snapshot'
]
exception_controller
:
class
:
Drupal\Core\Controller\ExceptionController
arguments
:
[
'
@content_negotiation'
,
'
@title_resolver'
,
'
@html_page_renderer'
,
'
@html_fragment_renderer'
,
'
@string_translation'
,
'
@url_generator'
,
'
@logger.factory'
]
calls
:
-
[
setContainer
,
[
'
@service_container'
]]
exception_listener
:
class
:
Drupal\Core\EventSubscriber\ExceptionListener
exception.default_json
:
class
:
Drupal\Core\EventSubscriber\ExceptionJsonSubscriber
tags
:
-
{
name
:
event_subscriber
}
exception.default_html
:
class
:
Drupal\Core\EventSubscriber\DefaultExceptionHtmlSubscriber
tags
:
-
{
name
:
event_subscriber
}
arguments
:
[
'
@html_fragment_renderer'
,
'
@html_page_renderer'
]
exception.default
:
class
:
Drupal\Core\EventSubscriber\DefaultExceptionSubscriber
tags
:
-
{
name
:
event_subscriber
}
arguments
:
[
'
@html_fragment_renderer'
,
'
@html_page_renderer'
,
'
@config.factory'
]
exception.logger
:
class
:
Drupal\Core\EventSubscriber\ExceptionLoggingSubscriber
tags
:
-
{
name
:
event_subscriber
}
arguments
:
[
'
@logger.factory'
]
exception.custom_page_json
:
class
:
Drupal\Core\EventSubscriber\ExceptionJsonSubscriber
tags
:
-
{
name
:
event_subscriber
}
arguments
:
[
'
@config.factory'
,
'
@path.alias_manager'
,
'
@http_kernel'
]
exception.custom_page_html
:
class
:
Drupal\Core\EventSubscriber\CustomPageExceptionHtmlSubscriber
tags
:
-
{
name
:
event_subscriber
}
arguments
:
[
'
@config.factory'
,
'
@path.alias_manager'
,
'
@http_kernel'
,
'
@logger.channel.php'
]
exception.fast_404_html
:
class
:
Drupal\Core\EventSubscriber\Fast404ExceptionHtmlSubscriber
tags
:
-
{
name
:
event_subscriber
}
arguments
:
[
'
@config.factory'
,
'
@http_kernel'
]
exception.test_site
:
class
:
Drupal\Core\EventSubscriber\ExceptionTestSiteSubscriber
tags
:
-
{
name
:
event_subscriber
}
arguments
:
[[
'
@exception_controller'
,
execute
]]
route_processor_manager
:
class
:
Drupal\Core\RouteProcessor\RouteProcessorManager
tags
:
...
...
core/includes/menu.inc
View file @
51a27d10
...
...
@@ -573,7 +573,7 @@ function menu_local_tasks($level = 0) {
$data
[
'actions'
]
=
array
();
$route_name
=
\
Drupal
::
routeMatch
()
->
getRouteName
();
if
(
!
empty
(
$route_name
))
{
if
(
!
\
Drupal
::
request
()
->
attributes
->
has
(
'exception'
)
&&
!
empty
(
$route_name
))
{
$manager
=
\
Drupal
::
service
(
'plugin.manager.menu.local_task'
);
$local_tasks
=
$manager
->
getTasksBuild
(
$route_name
);
foreach
(
$local_tasks
as
$level
=>
$items
)
{
...
...
core/lib/Drupal/Core/ContentNegotiation.php
View file @
51a27d10
...
...
@@ -23,7 +23,7 @@ class ContentNegotiation {
* The normalized type is a short, lowercase version of the format, such as
* 'html', 'json' or 'atom'.
*
* @param Symfony\Component\HttpFoundation\Request $request
* @param
\
Symfony\Component\HttpFoundation\Request $request
* The request object from which to extract the content type.
*
* @return string
...
...
core/lib/Drupal/Core/Controller/ExceptionController.php
deleted
100644 → 0
View file @
983cdbf0
<?php
/**
* @file
* Contains \Drupal\Core\Controller\ExceptionController.
*/
namespace
Drupal\Core\Controller
;
use
Drupal\Core\Logger\LoggerChannelFactoryInterface
;
use
Drupal\Core\Page\DefaultHtmlPageRenderer
;
use
Drupal\Core\Page\HtmlFragmentRendererInterface
;
use
Drupal\Core\Page\HtmlPageRendererInterface
;
use
Drupal\Core\Routing\UrlGeneratorInterface
;
use
Symfony\Component\DependencyInjection\ContainerAwareInterface
;
use
Symfony\Component\DependencyInjection\ContainerInterface
;
use
Symfony\Component\HttpFoundation\Request
;
use
Symfony\Component\HttpFoundation\Response
;
use
Symfony\Component\HttpFoundation\JsonResponse
;
use
Symfony\Component\HttpKernel\HttpKernelInterface
;
use
Drupal\Component\Utility\SafeMarkup
;
use
Drupal\Component\Utility\String
;
use
Symfony\Component\Debug\Exception\FlattenException
;
use
Drupal\Core\ContentNegotiation
;
use
Drupal\Core\Utility\Error
;
use
Drupal\Core\StringTranslation\StringTranslationTrait
;
use
Drupal\Core\StringTranslation\TranslationInterface
;
/**
* This controller handles HTTP errors generated by the routing system.
*/
class
ExceptionController
extends
HtmlControllerBase
implements
ContainerAwareInterface
{
use
StringTranslationTrait
;
/**
* The content negotiation library.
*
* @var \Drupal\Core\ContentNegotiation
*/
protected
$negotiation
;
/**
* The service container.
*
* @var \Symfony\Component\DependencyInjection\ContainerInterface
*/
protected
$container
;
/**
* The page rendering service.
*
* @var \Drupal\Core\Page\HtmlPageRendererInterface
*/
protected
$htmlPageRenderer
;
/**
* The fragment rendering service.
*
* @var \Drupal\Core\Page\HtmlFragmentRendererInterface
*/
protected
$fragmentRenderer
;
/**
* The logger factory service.
*
* @var \Drupal\Core\Logger\LoggerChannelFactoryInterface
*/
protected
$loggerFactory
;
/**
* Constructor.
*
* @param \Drupal\Core\ContentNegotiation $negotiation
* The content negotiation library to use to determine the correct response
* format.
* @param \Drupal\Core\Controller\TitleResolverInterface $title_resolver
* The title resolver.
* @param \Drupal\Core\Page\HtmlPageRendererInterface $renderer
* The page renderer.
* @param \Drupal\Core\Page\HtmlFragmentRendererInterface $fragment_renderer
* The fragment rendering service.
* @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
* The url generator.
* @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
* The URL generator.
* @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger_factory
* The logger factory.
*/
public
function
__construct
(
ContentNegotiation
$negotiation
,
TitleResolverInterface
$title_resolver
,
HtmlPageRendererInterface
$renderer
,
HtmlFragmentRendererInterface
$fragment_renderer
,
TranslationInterface
$string_translation
,
UrlGeneratorInterface
$url_generator
,
LoggerChannelFactoryInterface
$logger_factory
)
{
parent
::
__construct
(
$title_resolver
,
$url_generator
);
$this
->
negotiation
=
$negotiation
;
$this
->
htmlPageRenderer
=
$renderer
;
$this
->
fragmentRenderer
=
$fragment_renderer
;
$this
->
stringTranslation
=
$string_translation
;
$this
->
loggerFactory
=
$logger_factory
;
}
/**
* Sets the Container associated with this Controller.
*
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
* A ContainerInterface instance.
*
* @api
*/
public
function
setContainer
(
ContainerInterface
$container
=
NULL
)
{
$this
->
container
=
$container
;
}
/**
* Handles an exception on a request.
*
* @param \Symfony\Component\Debug\Exception\FlattenException $exception
* The flattened exception.
* @param \Symfony\Component\HttpFoundation\Request $request
* The request that generated the exception.
*
* @return \Symfony\Component\HttpFoundation\Response
* A response object.
*/
public
function
execute
(
FlattenException
$exception
,
Request
$request
)
{
$method
=
'on'
.
$exception
->
getStatusCode
()
.
$this
->
negotiation
->
getContentType
(
$request
);
if
(
method_exists
(
$this
,
$method
))
{
return
$this
->
$method
(
$exception
,
$request
);
}
return
new
Response
(
'A fatal error occurred: '
.
$exception
->
getMessage
(),
$exception
->
getStatusCode
(),
$exception
->
getHeaders
());
}
/**
* Processes a MethodNotAllowed exception into an HTTP 405 response.
*
* @param \Symfony\Component\Debug\Exception\FlattenException $exception
* The flattened exception.
* @param \Symfony\Component\HttpFoundation\Request $request
* The request object that triggered this exception.
*
* @return \Symfony\Component\HttpFoundation\Response
* A response object.
*/
public
function
on405Html
(
FlattenException
$exception
,
Request
$request
)
{
return
new
Response
(
'Method Not Allowed'
,
405
);
}
/**
* Processes an AccessDenied exception into an HTTP 403 response.
*
* @param \Symfony\Component\Debug\Exception\FlattenException $exception
* The flattened exception.
* @param \Symfony\Component\HttpFoundation\Request $request
* The request object that triggered this exception.
*
* @return \Symfony\Component\HttpFoundation\Response
* A response object.
*/
public
function
on403Html
(
FlattenException
$exception
,
Request
$request
)
{
// @todo Remove dependency on the internal _system_path attribute:
// https://www.drupal.org/node/2293523.
$system_path
=
$request
->
attributes
->
get
(
'_system_path'
);
$this
->
loggerFactory
->
get
(
'access denied'
)
->
warning
(
$system_path
);
$system_config
=
$this
->
container
->
get
(
'config.factory'
)
->
get
(
'system.site'
);
$path
=
$this
->
container
->
get
(
'path.alias_manager'
)
->
getPathByAlias
(
$system_config
->
get
(
'page.403'
));
if
(
$path
&&
$path
!=
$system_path
)
{
if
(
$request
->
getMethod
()
===
'POST'
)
{
$subrequest
=
Request
::
create
(
$request
->
getBaseUrl
()
.
'/'
.
$path
,
'POST'
,
array
(
'destination'
=>
$system_path
,
'_exception_statuscode'
=>
403
)
+
$request
->
request
->
all
(),
$request
->
cookies
->
all
(),
array
(),
$request
->
server
->
all
());
}
else
{
$subrequest
=
Request
::
create
(
$request
->
getBaseUrl
()
.
'/'
.
$path
,
'GET'
,
array
(
'destination'
=>
$system_path
,
'_exception_statuscode'
=>
403
),
$request
->
cookies
->
all
(),
array
(),
$request
->
server
->
all
());
}
$response
=
$this
->
container
->
get
(
'http_kernel'
)
->
handle
(
$subrequest
,
HttpKernelInterface
::
SUB_REQUEST
);
$response
->
setStatusCode
(
403
,
'Access denied'
);
}
else
{
$page_content
=
array
(
'#markup'
=>
$this
->
t
(
'You are not authorized to access this page.'
),
'#title'
=>
$this
->
t
(
'Access denied'
),
);
$fragment
=
$this
->
createHtmlFragment
(
$page_content
,
$request
);
$page
=
$this
->
fragmentRenderer
->
render
(
$fragment
,
403
);
$response
=
new
Response
(
$this
->
htmlPageRenderer
->
render
(
$page
),
$page
->
getStatusCode
());
return
$response
;
}
return
$response
;
}
/**
* Processes a NotFound exception into an HTTP 404 response.
*
* @param \Symfony\Component\Debug\Exception\FlattenException $exception
* The flattened exception.
* @param \Symfony\Component\HttpFoundation\Request $request
* The request object that triggered this exception.
*
* @return \Symfony\Component\HttpFoundation\Response
* A response object.
*/
public
function
on404Html
(
FlattenException
$exception
,
Request
$request
)
{
$this
->
loggerFactory
->
get
(
'page not found'
)
->
warning
(
String
::
checkPlain
(
$request
->
attributes
->
get
(
'_system_path'
)));
// Check for and return a fast 404 page if configured.
$config
=
\
Drupal
::
config
(
'system.performance'
);
$exclude_paths
=
$config
->
get
(
'fast_404.exclude_paths'
);
if
(
$config
->
get
(
'fast_404.enabled'
)
&&
$exclude_paths
&&
!
preg_match
(
$exclude_paths
,
$request
->
getPathInfo
()))
{
$fast_paths
=
$config
->
get
(
'fast_404.paths'
);
if
(
$fast_paths
&&
preg_match
(
$fast_paths
,
$request
->
getPathInfo
()))
{
$fast_404_html
=
$config
->
get
(
'fast_404.html'
);
$fast_404_html
=
strtr
(
$fast_404_html
,
array
(
'@path'
=>
String
::
checkPlain
(
$request
->
getUri
())));
return
new
Response
(
$fast_404_html
,
404
);
}
}
// @todo Remove dependency on the internal _system_path attribute:
// https://www.drupal.org/node/2293523.
$system_path
=
$request
->
attributes
->
get
(
'_system_path'
);
$path
=
$this
->
container
->
get
(
'path.alias_manager'
)
->
getPathByAlias
(
\
Drupal
::
config
(
'system.site'
)
->
get
(
'page.404'
));
if
(
$path
&&
$path
!=
$system_path
)
{
// @todo Um, how do I specify an override URL again? Totally not clear. Do
// that and sub-call the kernel rather than using meah().
// @todo The create() method expects a slash-prefixed path, but we store a
// normal system path in the site_404 variable.
if
(
$request
->
getMethod
()
===
'POST'
)
{
$subrequest
=
Request
::
create
(
$request
->
getBaseUrl
()
.
'/'
.
$path
,
'POST'
,
array
(
'destination'
=>
$system_path
,
'_exception_statuscode'
=>
404
)
+
$request
->
request
->
all
(),
$request
->
cookies
->
all
(),
array
(),
$request
->
server
->
all
());
}
else
{
$subrequest
=
Request
::
create
(
$request
->
getBaseUrl
()
.
'/'
.
$path
,
'GET'
,
array
(
'destination'
=>
$system_path
,
'_exception_statuscode'
=>
404
),
$request
->
cookies
->
all
(),
array
(),
$request
->
server
->
all
());
}
$response
=
$this
->
container
->
get
(
'http_kernel'
)
->
handle
(
$subrequest
,
HttpKernelInterface
::
SUB_REQUEST
);
$response
->
setStatusCode
(
404
,
'Not Found'
);
}
else
{
$page_content
=
array
(
'#markup'
=>
$this
->
t
(
'The requested page "@path" could not be found.'
,
array
(
'@path'
=>
$request
->
getPathInfo
())),
'#title'
=>
$this
->
t
(
'Page not found'
),
);
$fragment
=
$this
->
createHtmlFragment
(
$page_content
,
$request
);
$page
=
$this
->
fragmentRenderer
->
render
(
$fragment
,
404
);
$response
=
new
Response
(
$this
->
htmlPageRenderer
->
render
(
$page
),
$page
->
getStatusCode
());
return
$response
;
}
return
$response
;
}
/**
* Processes a generic exception into an HTTP 500 response.
*
* @param \Symfony\Component\Debug\Exception\FlattenException $exception
* Metadata about the exception that was thrown.
* @param \Symfony\Component\HttpFoundation\Request $request
* The request object that triggered this exception.
*
* @return \Symfony\Component\HttpFoundation\Response
* A response object.
*/
public
function
on500Html
(
FlattenException
$exception
,
Request
$request
)
{
$error
=
$this
->
decodeException
(
$exception
);
// Because the kernel doesn't run until full bootstrap, we know that
// most subsystems are already initialized.
$headers
=
array
();
// When running inside the testing framework, we relay the errors
// to the tested site by the way of HTTP headers.
if
(
DRUPAL_TEST_IN_CHILD_SITE
&&
!
headers_sent
()
&&
(
!
defined
(
'SIMPLETEST_COLLECT_ERRORS'
)
||
SIMPLETEST_COLLECT_ERRORS
))
{
// $number does not use drupal_static as it should not be reset
// as it uniquely identifies each PHP error.
static
$number
=
0
;
$assertion
=
array
(
$error
[
'!message'
],
$error
[
'%type'
],
array
(
'function'
=>
$error
[
'%function'
],
'file'
=>
$error
[
'%file'
],
'line'
=>
$error
[
'%line'
],
),
);
$headers
[
'X-Drupal-Assertion-'
.
$number
]
=
rawurlencode
(
serialize
(
$assertion
));
$number
++
;
}
$this
->
loggerFactory
->
get
(
'php'
)
->
log
(
$error
[
'severity_level'
],
'%type: !message in %function (line %line of %file).'
,
$error
);
// Display the message if the current error reporting level allows this type
// of message to be displayed, and unconditionnaly in update.php.
if
(
error_displayable
(
$error
))
{
$class
=
'error'
;
// If error type is 'User notice' then treat it as debug information
// instead of an error message.
// @see debug()
if
(
$error
[
'%type'
]
==
'User notice'
)
{
$error
[
'%type'
]
=
'Debug'
;
$class
=
'status'
;
}
// Attempt to reduce verbosity by removing DRUPAL_ROOT from the file path
// in the message. This does not happen for (false) security.
$root_length
=
strlen
(
DRUPAL_ROOT
);
if
(
substr
(
$error
[
'%file'
],
0
,
$root_length
)
==
DRUPAL_ROOT
)
{
$error
[
'%file'
]
=
substr
(
$error
[
'%file'
],
$root_length
+
1
);
}
// Should not translate the string to avoid errors producing more errors.
$message
=
String
::
format
(
'%type: !message in %function (line %line of %file).'
,
$error
);
// Check if verbose error reporting is on.
$error_level
=
$this
->
container
->
get
(
'config.factory'
)
->
get
(
'system.logging'
)
->
get
(
'error_level'
);
if
(
$error_level
==
ERROR_REPORTING_DISPLAY_VERBOSE
)
{
$backtrace_exception
=
$exception
;
while
(
$backtrace_exception
->
getPrevious
())
{
$backtrace_exception
=
$backtrace_exception
->
getPrevious
();
}
$backtrace
=
$backtrace_exception
->
getTrace
();
// First trace is the error itself, already contained in the message.
// While the second trace is the error source and also contained in the
// message, the message doesn't contain argument values, so we output it
// once more in the backtrace.
array_shift
(
$backtrace
);
// Generate a backtrace containing only scalar argument values.
$message
.
=
'<pre class="backtrace">'
.
Error
::
formatFlattenedBacktrace
(
$backtrace
)
.
'</pre>'
;
}
drupal_set_message
(
SafeMarkup
::
set
(
$message
),
$class
,
TRUE
);
}
$content
=
$this
->
t
(
'The website has encountered an error. Please try again later.'
);
$output
=
DefaultHtmlPageRenderer
::
renderPage
(
$content
,
$this
->
t
(
'Error'
));
$response
=
new
Response
(
$output
);
$response
->
setStatusCode
(
500
,
'500 Service unavailable (with message)'
);
return
$response
;
}
/**
* Processes an AccessDenied exception that occurred on a JSON request.
*
* @param \Symfony\Component\Debug\Exception\FlattenException $exception
* The flattened exception.
* @param \Symfony\Component\HttpFoundation\Request $request
* The request object that triggered this exception.
*
* @return \Symfony\Component\HttpFoundation\JsonResponse
* A JSON response object.
*/
public
function
on403Json
(
FlattenException
$exception
,
Request
$request
)
{
$response
=
new
JsonResponse
();
$response
->
setStatusCode
(
403
,
'Access Denied'
);
return
$response
;
}
/**
* Processes a NotFound exception that occurred on a JSON request.
*
* @param \Symfony\Component\Debug\Exception\FlattenException $exception
* The flattened exception.
* @param \Symfony\Component\HttpFoundation\Request $request
* The request object that triggered this exception.
*
* @return \Symfony\Component\HttpFoundation\JsonResponse
* A JSON response object.
*/
public
function
on404Json
(
FlattenException
$exception
,
Request
$request
)
{
$response
=
new
JsonResponse
();
$response
->
setStatusCode
(
404
,
'Not Found'
);
return
$response
;
}
/**
* Processes a MethodNotAllowed exception that occurred on a JSON request.
*
* @param \Symfony\Component\Debug\Exception\FlattenException $exception
* The flattened exception.
* @param \Symfony\Component\HttpFoundation\Request $request
* The request object that triggered this exception.
*
* @return \Symfony\Component\HttpFoundation\JsonResponse
* A JSON response object.
*/
public
function
on405Json
(
FlattenException
$exception
,
Request
$request
)
{
$response
=
new
JsonResponse
();
$response
->
setStatusCode
(
405
,
'Method Not Allowed'
);
return
$response
;
}
/**
* This method is a temporary port of _drupal_decode_exception().
*
* @todo This should get refactored. FlattenException could use some
* improvement as well.
*
* @param \Symfony\Component\Debug\Exception\FlattenException $exception
* The flattened exception.
*
* @return array
* An array of string-substitution tokens for formatting a message about the
* exception.
*/
protected
function
decodeException
(
FlattenException
$exception
)
{
$message
=
$exception
->
getMessage
();
$backtrace
=
$exception
->
getTrace
();
// This value is missing from the stack for some reason in the
// FlattenException version of the backtrace.
$backtrace
[
0
][
'line'
]
=
$exception
->
getLine
();
// For database errors, we try to return the initial caller,
// skipping internal functions of the database layer.
if
(
strpos
(
$exception
->
getClass
(),
'DatabaseExceptionWrapper'
)
!==
FALSE
)
{
// A DatabaseExceptionWrapper exception is actually just a courier for
// the original PDOException. It's the stack trace from that exception
// that we care about.
$backtrace
=
$exception
->
getPrevious
()
->
getTrace
();
$backtrace
[
0
][
'line'
]
=
$exception
->
getLine
();
// The first element in the stack is the call, the second element gives us the caller.
// We skip calls that occurred in one of the classes of the database layer
// or in one of its global functions.
$db_functions
=
array
(
'db_query'
,
'db_query_range'
);
while
(
!
empty
(
$backtrace
[
1
])
&&
(
$caller
=
$backtrace
[
1
])
&&
((
strpos
(
$caller
[
'namespace'
],
'Drupal\Core\Database'
)
!==
FALSE
||
strpos
(
$caller
[
'class'
],
'PDO'
)
!==
FALSE
))
||
in_array
(
$caller
[
'function'
],
$db_functions
))
{
// We remove that call.
array_shift
(
$backtrace
);
}
}
$caller
=
Error
::
getLastCaller
(
$backtrace
);
return
array
(
'%type'
=>
$exception
->
getClass
(),
// The standard PHP exception handler considers that the exception message
// is plain-text. We mimick this behavior here.
'!message'
=>
String
::
checkPlain
(
$message
),
'%function'
=>
$caller
[
'function'
],
'%file'
=>
$caller
[
'file'
],
'%line'
=>
$caller
[
'line'
],
'severity_level'
=>
WATCHDOG_ERROR
,
);
}
}
core/lib/Drupal/Core/EventSubscriber/AuthenticationSubscriber.php
View file @
51a27d10
...
...
@@ -70,8 +70,8 @@ public function onException(GetResponseForExceptionEvent $event) {
* Cookie provider to send all relevant session data to the user.
*/
public
static
function
getSubscribedEvents
()
{
$events
[
KernelEvents
::
RESPONSE
][]
=
array
(
'onRespond'
,
0
)
;
$events
[
KernelEvents
::
EXCEPTION
][]
=
array
(
'onException'
,
0
)
;
$events
[
KernelEvents
::
RESPONSE
][]
=
[
'onRespond'
,
0
]
;
$events
[
KernelEvents
::
EXCEPTION
][]
=
[
'onException'
,
75
]
;
return
$events
;
}
}
core/lib/Drupal/Core/EventSubscriber/CustomPageExceptionHtmlSubscriber.php
0 → 100644
View file @
51a27d10
<?php
/**
* @file
* Contains \Drupal\Core\EventSubscriber\DefaultExceptionHtmlSubscriber.
*/
namespace
Drupal\Core\EventSubscriber
;
use
Drupal\Core\Config\ConfigFactoryInterface
;
use
Drupal\Core\Path\AliasManagerInterface
;
use
Drupal\Core\Utility\Error
;
use
Psr\Log\LoggerInterface
;
use
Symfony\Component\HttpFoundation\Request
;
use
Symfony\Component\HttpFoundation\Response
;
use
Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent
;
use
Symfony\Component\HttpKernel\HttpKernelInterface
;
/**
* Exception subscriber for handling core custom error pages.
*/
class
CustomPageExceptionHtmlSubscriber
extends
HttpExceptionSubscriberBase
{
/**
* The configuration factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected
$configFactory
;
/**
* The page alias manager.
*
* @var \Drupal\Core\Path\AliasManagerInterface
*/
protected
$aliasManager
;
/**
* The HTTP kernel.
*
* @var \Symfony\Component\HttpKernel\HttpKernelInterface