Error and Exception Handling
Flow reports applications errors by throwing specific exceptions. Exceptions are structured in a hierarchy which is based on base exception classes for each component. By default, PHP catchable errors, warnings and notices are automatically converted into exceptions in order to simplify the error handling.
In case an exception cannot be handled by the application, a central exception handler takes over to display or log the error and shut down the application gracefully.
Throwing Exceptions
Applications should throw exceptions which are based on one of the exception classes provided by Flow. Each exception should be identified by a unique error code which is, by convention, the unix timestamp of the point in time when the developer implemented the code throwing the exception:
if ($somethingWentReallyWrong) {
throw new SomethingWentWrongException('An exception message', 1347145643);
}
Exceptions can contain an HTTP status code which is sent as a corresponding response header. The status code is simply set by defining a property with the respective value assigned:
class SomethingWasNotFoundException extends \Neos\Flow\Exception {
/**
* @var integer
*/
protected $statusCode = 404;
}
Exception Handlers
Flow comes with two different exception handlers:
the
DebugExceptionHandler
displays a big amount of background information, including a call stack, in order to simplify debugging of the exception cause. The output might contain sensitive data because method arguments are displayed in the backtrace.the
ProductionExceptionHandler
displays a neutral message stating that an error occurred. Apart from a reference code no information about the nature of the exception or any parameters is disclosed.
By default, the DebugExceptionHandler
is used in Development context and the
ProductionExceptionHandler
is in charge in the Production context.
The exception handler to be used can be configured through an entry in Settings.yaml:
Neos:
Flow:
error:
exceptionHandler:
# Defines the global, last-resort exception handler.
# The specified class must implement \Neos\Flow\Error\ExceptionHandlerInterface
className: 'Neos\Error\Messages\ProductionExceptionHandler'
Reference Code
In a production context, the exception handler should, for security reasons, not reveal any information about the inner workings and data of the application. In order to be able to track down the root of the problem, Flow generates a unique reference code when an exception is thrown. It is safe to display this reference code to the user who can, in turn, contact the administrators of the application to report the error. At the server side, detailed information about the exception is stored in a file named after the reference code.
You will find report files for exceptions thrown in Data/Logs/Exceptions/
. In
some rare cases though, when Flow is not even able to write the respective log
file, no details about the exception can be provided.
Error Handler
Flow provides a central error handler which jumps in if a PHP error, warning or
notice occurs. Instead of displaying or logging the error right away, it is
transformed into an ErrorException
.
A configuration option in Settings.yaml allows for deciding which error levels should be converted into exceptions. All other errors are silently ignored:
Neos:
Flow:
error:
errorHandler:
# Defines which errors should result in an exception thrown - all other error
# levels will be silently ignored. Only errors that can be handled in an
# user-defined error handler are affected, of course.
exceptionalErrors: ['%E_USER_ERROR%', '%E_RECOVERABLE_ERROR%']
Custom Error Views
In order to allow customized, specifically looking error templates; even depending on the nature of an error; Flow provides configurable rendering groups. Each such rendering group holds information about what template to use, what text information should be provided, and finally, what HTTP status codes or what Exception class names each rendering group is responsible for.
An example configuration could look like in the following Settings.yaml excerpt:
Neos:
Flow:
error:
exceptionHandler:
defaultRenderingOptions: []
renderingGroups:
notFoundExceptions:
matchingStatusCodes: [404]
options:
viewClassName: 'Neos\FluidAdaptor\View\StandaloneView'
viewOptions:
templatePathAndFilename: 'resource://Neos.Flow/Private/Templates/Error/Default.html'
variables:
errorDescription: 'Sorry, the page you requested was not found.'
databaseConnectionExceptions:
matchingExceptionClassNames: ['Neos\Flow\Persistence\Doctrine\DatabaseConnectionException']
options:
viewClassName: 'Neos\FluidAdaptor\View\StandaloneView'
viewOptions:
templatePathAndFilename: 'resource://Neos.Flow/Private/Templates/Error/Default.html'
variables:
errorDescription: 'Sorry, the database connection couldn''t be established.'
defaultRenderingOptions
:this carries default options which can be overridden by the
options
key of a particular rendering group; see below.
notFoundExceptions
and databaseConnectionExceptions
are freely chosen, descriptive
key names, their actual naming has no further implications.
matchingStatusCodes
:an array of integer values what HTTP status codes the rendering group is for
matchingExceptionClassNames
:an array of string values what Exception types the rendering group is for. Keep in mind that, as always the class name must not contain a leading slash, but must be fully qualified, of course.
options
:
logException
:a boolean telling Flow to log the exception and write a backtrace file. This is on by default but switched off for exceptions with a 404 status code
renderTechnicalDetails
:a boolean passed to the error template during rendering and used in the default error template to include more details on the error at hand. Defaults to false but is set to true for development context.
viewClassName
:a class name of the view that should be used
viewOptions
:an array of options handed to the view. See
$supportedOptions
of the used viewvariables
an array of additional, arbitrary variables which can be accessed in the template
The following variables will be assigned to the template an can be used there:
exception
:the Exception object which was thrown
renderingOptions
:the complete rendering options array, as defined in the settings. This is a merge of
Neos.Flow.error.exceptionHandler.defaultRenderingOptions
and theoptions
array of the particular rendering groupstatusCode
:the integer value of the HTTP status code which has been thrown (
404
,503
etc.)statusMessage
:the HTTP status message equivalent, for example
Not Found
,Service Unavailable
etc. If no matching status message could be found, this value isUnknown Status
.referenceCode
:the reference code of the exception, if applicable.