Capture or modify Laravel's error pages? - php

I'd like to insert a code snippet into Laravel's error pages, but I can't figure out how to modify or capture the output.
This filthy hack seems to work, but the snippet is inserted before any page code.
// In laravel/app/start/global.php
App::error(function (Exception, $exception, $code)
{
echo '<script src="//localhost:35729/livereload.js"></script>';
});

The error pages are in resources/views/errors. You can then simply add whatever you want inside those file by naming them with the status code like 503.blade.php.
You can even make a base error page and the other view extends this one.
You can also take a look at the \App\Exceptions\Handler class in the report method, you can check Exceptions that have been thrown there.

Related

Laravel, how to redirect to other page if my views have errors(any types)?

The title says it all, but the problem is, i don't know how to catch errors in views. I have read other solutions in SO, but try catch is not recommended in views.
Assume the controller has no error whatsoever, lets say my views has undefined variables in xxx lines, and i wanted to redirect to other page immediately without the user realize.
How do I achieve this goal? I already tried searching for answer but does not really help at all.
Okay I found some workaround for your case
First you need to create a file in resources/views/errors/500.blade.php
in that file you should put some javascript that redirect to url you want in onLoad event.
window.location = 'url/you/want'
and then you have to modify report() function in App/Exceptions/Handler.php to something like this
public function report(Exception $exception){
abort(500);
parent::report($exception);
}
Beware though. Once you do something like this, You controller will throw every unhandled exception and redirect to url you specified earlier in the blade file
PS: The view itself should not have any error in any cases. You have to make sure the controller return all the value the view needs instead of handling error in views.
You'd have to use
header("Refresh:0; url=foo.php");
Where 0 is the time waited before actually redirecting. But since you stated for no one to even realize, this might be the solution for you.

Change "Whoops, looks like something went wrong." message

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

How to render an action from another action in Symfony 1

I am stuck with a Symfony application using version 1.0.17 which can't be upgraded at the moment.
Right now there is a page that contains an iframe which loads a webpage of a different action from the same module. The iframe is causing some design issues as well and some user-experience issues so I want to get rid of it and just render the HTML from the iframe directly in the page.
I just can't figure out how to execute another action and render the view template into a variable that I can assign to the calling action's view.
I've tried getPresentationFor() but that either results in a 404 on the calling page, an exception or fatal error depending on how I try it.
I think I need to put the code in the execute method of the action. The controller is an sfAction object. If I call $this->getController() I get an sfWebController object.
Calling:
$this->getController()->getPresentationFor('module', 'ContactIframeAction');
Results in a blank page; any code after that call does not get executed but if I output something before it I can see it on the page. No errors in the server error log.
Calling:
$this->getController()->getPresentationFor('module', 'ContactIframe');
just causes our 404 page to show so I think the previous call is closer to what I want.
Is there a way to render the output of another action from another action's code?
Thanks.
It's probably
$this->theContent = $this->getController()->getPresentationFor('module', 'contactIframe'); // minus 'c'
Use :
// modules/mymodule/actions/actions.class.php
class myPageActions extends sfActions {
public function executeIndex() {
// ...
$this->theContent = $this->getController()->getPresentationFor('module', 'contactIframe');
}
}
// modules/mymodule/templates/indexSuccess.php
<?php echo $theContent ?>

CakePHP 2.0+ custom error views using exceptions

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>
<? } ?>

stopping page not found errors when controller does not exist

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
}

Categories