In production mode (minimal errors), when a controller is not found, Zend gives a 404 page not found error. There are a couple of controllers that I don't want this activated for. Even though they don't exist, I don't want the page not found error activated. Is it possible to somehow block that error and give an empty page. I'm guessing, if at all possible, it has to be done at the plugin level since no controller really exists to handle this.
One possible solution would be to check the request object in your errorAction for controller and/or action that threw the exceptions (for non-existing controllers and actions you could also get their names this way). Based on this you could customize the rest of errorAction. For example:
public function errorAction() {
$errors = $this->_getParam('error_handler');
$whatController = $errors->request->getControllerName();
if ('secretController' == $whatController) {
return $this->_redirect('blankErrorPage');
}
// usual rest of errorAction
}
Related
I need to throw an Exception inside service
$isLangExist = $this->em->getRepository('TranslationBundle:Language')->findOneBy(array(
'locale' => $this->request->getMasterRequest()->getLocale()
));
if (!$isLangExist) {
throw new createNotFoundException('you are using unavailable langage');
}
but I got this page is not workinc in prod env
how can i show 404 page with createNotFoundException or any another Exception type
thanks
It looks like your code is not correct. I would expect it to look like this:
if (!$isLangExist) {
throw $this->createNotFoundException('you are using unavailable langage');
}
The method is part of the abstract base controller you can use, but it's not mandatory. What should work in cases where you don't extend this controller is:
if (!$isLangExist) {
throw new NotFoundHttpException('you are using unavailable langage');
}
Your problem goes beyond the above code, because you don't throw the exception inside a controller as I expected. You throw it inside a Twig extension. This exception will interrupt rendering, which is why the error is not converted into a 404 exception and instead is treated as a 500 error. Potentially you will see other 500-errors with your extension whenever one of the queries fails, which is probably not what you want. Addressing this issue likely requires rethinking how you use these global twig variables.
You could try moving the templates that use these variables into separate templates being rendered by a dedicated controller using sub requests or ESI:
{{
render(controller(
'AppBundle:Global:_listCategories',
{
'locale': app.request.attributes.get('_locale')
}
))
}}
Another solution might be to set these with null or an error-object whenever something fails and then react to these "alternative" results in your template, which is not what I would prefer.
There are probably many other ways to tackle this. The gist is: rendering error are different than http-exceptions thrown by controllers services. You have to ensure that your templates can either be rendered despite these missing/faulty variables or deal with these missing parameters before rendering the templates, e.g. in an event listener.
I would like to show a custom error page when the reporting level is set to 0 and it is a 500 error not a 404. It seems I can't access the error message at all, outside of the default view.
I would like to set a custom layout outside of the normal error layouts. I know if I switch the reporting to level 1 or 2 then it works fine. I want this for production where it is set at 0 and not a 400 error. Is this possible?
$error->getMessage()
Q: I would like to show a custom error page when the reporting level is set to 0 and it is a 500 error
A: You can edit the default error views error400.ctp and also error500.ctp in /app/View/Errors/
Q: I would like to set a custom layout outside of the normal error layouts.
A: If you want to use another (custom) layout you can copy the file CakeErrorController.php from /lib/Cake/Controller/ to /app/Controller/ and add the following line in the function:
function __construct($request = null, $response = null) {
$this->layout = 'your-layout-name'; // add this line in the function
// ...
}
and add the custom layout template file as usual in /app/View/Layouts/, e.g. your-layout-name.ctp
If you want to show data from your app in the error page/layout (eg generate the main menu from the database) you can add more custom code in your error controller as well, e.g.:
// Error controller in /app/Controller/CakeErrorController.php
class CakeErrorController extends AppController {
public $uses = array('MenuCategory'); // load relevant table/model
public function __construct($request = null, $response = null) {
$this->set('mainmenu', $this->MenuCategory->getMenu()); // or find() or whatever
// ...
}
}
Q: How can I keep different error messages in production mode (debug level = 0)?
A According to the documentation "ErrorHandler by default, displays errors when debug > 0, and logs errors when debug = 0." The reason is e.g. that you should not show your public visitors (in production mode) an error message like "Missing Component", because this error is irrelevant and not useful for the visitor (so a 404/500 is responded). These kind of errors are only relevant for development and should be fixed before you go live in production mode.
If you want to change this behaviour you have to set up your own error handling as it is exlained in the book. Please also have a look at the explanation directly in the CakePHP code. You can also create your own exeptions if necessary.
If you have problems in using/creating your own error handler, please start a new question on Stackoverflow with more details: What files have you created (e.g. your error handler and/or exceptions), how is your code looking like, what have you tried to solve the problem... and please give a clear example of what you want to achieve (e.g. in the comments below to the first version of my answer you are talking about special 500 errors - What is triggering these errors and what do you want to response instead of a 500 or what exactly do you want to change...)?
An alternative solution in some situations could also be something like this:
// In your controller
public function moderator_view($id = null) {
// Your error check, in this example the user role
if ( $this->Auth->user('role') != 'moderator' ) {
// Custom error message
$this->Flash->custom('You are not a moderator.');
// Redirect to your your special error page
// In this example got to previous page
return $this->redirect(
$this->referer(
// or go to a default page if no referrer is given
array('controller' => 'articles', 'action' => 'index', 'moderator' => false)
)
);
}
// else show moderator content...
}
Please also have a look at the many other questions to custom error pages in CakePHP ;-)
I'm sure I'm missing something silly here. I'm trying to replace the non-debug error screen that Laravel throws when there's an exception. It seems to be ignoring the code below (placed in start/global.php):
App::error(function(Exception $exception, $code)
{
Log::error($exception);
if(!Config::get('app.debug')) {
return Response::view('errors.exception', ['message' => $exception->getMessage()], 500);
}
});
Why would it ignore that? And was I supposed to do something elsewhere as well?
Bit of clarity:
I'm testing this with a QueryException (HY000). But surely this should not make a difference?
Using Laravel 4.2
It'd be hard to say without seeing your system, but my first guess would be there's another call to App:error made after yours that overrides what's you're trying to do in app/global.php.
I just wrote about how Laravel sets up it's error handling recently. After reading that article (or maybe skipping it and diving in), the way I'd debug this would be to hop into
vendor/laravel/framework/src/Illuminate/Exception/Handler.php
and look at the definition of callCustomHandlers. This is the method that calls any handlers setup via App:error
protected function callCustomHandlers($exception, $fromConsole = false)
{
foreach ($this->handlers as $handler)
{
//...
}
}
Your handler will be in the $this->handlers array. I'd add some temporary debugging code to this class (the class may be in Laravel's single combined optimized file) to determine
If your handler fails the handlesException test
If there's another handler added to the queue after your that "wins" and sends a response.
It also never hurts to start with a
App::error(function()
{
exit(__FILE__);
});
and then build out your error handler until it stops being called. That way you know what part of it Laravel's having a problem with.
In app/global.php there is a default error handler setup. You will want to remove that to use yours, or just modify that one.
Check this out for more information... http://laravel.com/docs/errors#handling-errors
I'm trying to add my custom pages. I'm using Kohana 3.3. The official documentation states that I should ovveride the method hander of native Kohana_Exception class. This is pretty easy to do so I've done that. Now I'm expecting that Kohana would call that method every time an exception or an error occurs. But this is not the case. I've found 2 catch blocks where an exception is caught inside execute_request method of Kohana_Request_Client_Internal class.
First catch
catch (HTTP_Exception $e)
{
// Get the response via the Exception
$response = $e->get_response();
}
Second catch
catch (Exception $e)
{
// Generate an appropriate Response object
$response = Kohana_Exception::_handler($e);
}
As you can see, none of the catch blocks calls handler method overriden by me.
Setting your own exception handler set_exception_handler has no effect since it is applied only to uncaught exceptions and the exceptions like 404 are thrown and caught.
No problems with run-time errors though. This block catches them and explicitly calls overriden handler method.
if (Kohana::$errors AND $error = error_get_last() AND in_array($error['type'],
Kohana::$shutdown_errors))
{
// Clean the output buffer
ob_get_level() AND ob_clean();
// Fake an exception for nice debugging
Kohana_Exception::handler(new ErrorException($error['message'], $error['type'], 0, $error['file'], $error['line']));
// Shutdown now to avoid a "death loop"
exit(1);
}
So my question how do I set up everything to have custom error page for Exception and HTTP_Exception?
PS. I can ovveride HTTP_Exception_404 and HTTP_Exception_500 to have my custom error page displayed, but I don't think that's the best option since it could work for these two, but overriding all possible HTTP_Exceptions is not a good way to go.
PS2. Or I can set my custom view in bootstrap.php:
Kohana_Exception::$error_view = 'custom_error.tpl';
Also don't like that solution.
All links to Kohana's documentation in this post are for version 3.3
You won't get what you want by overwriting just one method. Below I explain the methods that you can overwrite in order to achieve what you want. Just make just sure you put the right code in the right method.
Don't try to do everything in one place. While it will be all in one place is will most likely become a mess.
Kohana_Exception::handler()
Kohana_Exception::handler() is for when exceptions reach the exception handler or like you showed, in the shutdown handler. The last chance you have to display a nice error page in production environments. It outputs the result of Kohana_exception::_handler(), which is a Response object, and is therefor not suited to be called inside Request_Client_Internal::execute_response().
For production: Log the original exception. Since this scenario matches the description of HTTP Status Code 500 (Internal Server Error) Kohana_Exception::handler() should display a 500 error page.
During development you probably want to call parent::handler().
Kohana_Exception::_handler()
Kohana_Exception::_handler() return a Response object, so it is suited to be called in Request_Client_External::execute_response(), Kohana_Exception::handler() and View::__toString().
HTTP_Exception::get_response()
HTTP_Exception::get_response() will get called for exceptions extending HTTP_Exception, with the exception of exceptions extending HTTP_Exception_Expected. A few examples of exceptions extending HTTP_Expected_Exception are the 3xx and 401 HTTP_Exceptions.
By default it returns Kohana_Exception::response().
Overwrite it in specific exceptions to return specific responses for said exception.
Overwrite it in HTTP_Exception when you want the replace the default response.
Kohana_Exception::response()
Kohana_Exception::response() is responsible for collecting the data needed to render the Kohana_Exception::$error_view template. An example of output can be seen on the kohana/errors page of the userguide.
Change Kohana_Exception::$error_view when you want a different layout for the same data.
Overwrite Kohana_Exception::response() to replace the entire thing.
PS. Kevin pointed you to the 3.2 documentation. How to do this is very different for 3.2 and 3.3.
I have been reading the following question here: CakePHP 2.0 - How to make custom error pages?
About creating custom views for exception handling in CakePHP 2.0+ and have been using it as a base to start doing the same in my own application hence starting my own question.
However I'm not following the logic. For example how does the Throw NotFoundException know to call the notFound method in the Errors Controller as I don't see any direct relationship in terms of the naming... Unless I'm missing the point?
In any case I'm looking to add 404, 403, and 401 errors and then be able to create custom views and call them using the exception handler throughout my app.
Can anyone shed more light on this? I'm using the latest version of Cake 2.1
So I have the following code:
App::uses('ExceptionRenderer', 'Error');
class AppExceptionRenderer extends ExceptionRenderer {
public function notFound($error) {
$this->controller->redirect(array('controller' => 'errors', 'action' => 'error404'));
}
}
And I want to replace that redirect with rendering a custom error view:
I've tried:
$this->controller->layout = null;
$this->controller->render('/Errors/error404');
But that just shows a blank page... Can anyone help me out as I don't want to do the redirect and would much rather follow conventions and render actual views with the same url when getting errors.
Update: Also noticed that the custom views ONLY get called when exceptions are manually called in the controller, and not for actual errors such as domain.com/garbageurl or something else... So it doesn't seem to be doing what I thought!
Have a look at these files from core Cake:
Cake/Error/ErrorHandler.php
Cake/Error/ExceptionRenderer.php
Here's what's happening:
ErrorHandler::handleException() is your exception handler. It gets called when an exception is thrown.
ErrorHandler::handleException() calls ExceptionRenderer::__construct() (your custom exception renderer must extend ExceptionRenderer) which parses the name of the Exception that was thrown, and from that, sets $this->method.
ErrorHandler::handleException() then calls ExceptionRenderer::render() which uses call_user_func_array() to call the method whose name is $this->method.
I was just looking for the same thing and could not find a neat way to do this using AppExceptionRenderer. It just won't allow you to have separate error403 and error404 template files.
So I just did this in my /app/View/Errors/error400.ctp file instead...
<? if ($error instanceof ForbiddenException) { ?>
<h4>Whoops! The page you attempted to access
requires permissions that you don't have.</h4>
<? } else { ?>
<h4>Whoops! We couldn't find the page you were looking for, sorry!</h4>
<? } ?>