Symfony Throw custom 404 page inside service - php

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.

Related

Laravel stops executing when an Exception occurred and displaying the message using some default template - Handling exceptions in laravel

I am using latest version laravel(5.6)
Now in my code whenever an exception occurs laravel treating it as a fatal error, stop executing instantly and displaying the error message in some template.
But I don't want that, I want to handle exceptions and display some custom error messages
I found some ways like
changing the APP_DEBUG value in the .env file to false. But this also displays another
page with the message "whoops!some this want wrong";
In Handler.php which is in app/Exceptions, I had put some exceptions in not report zone. But the app is still reporting them
Custom HTTP Error Pages
Laravel makes it easy to display custom error pages for various HTTP
status codes. For example, if you wish to customize the error page for
404 HTTP status codes, create a resources/views/errors/404.blade.php.
This file will be served on all 404 errors generated by your
application. The views within this directory should be named to match
the HTTP status code they correspond to. The HttpException instance
raised by the abort function will be passed to the view as an
$exception variable.
https://laravel.com/docs/5.6/errors#custom-http-error-pages
Really you want to be handling your exceptions. Wrap the code in a try catch and you can do all manner of things (e.g. email / slack / log). Once you have handled the exception you can still use custom http error pages inside the catch so the end user get's a friendly message on a nicely designed page. There is even a report helper built in to allow you to externally log and continue on processing the code.
#Devon's above answer re: Custom HTTP Error Pages gets you exactly what you want also.
Please note few important points :
The App\Exceptions\Handler class is where all exceptions triggered by your application are logged and then rendered back to the user. This class has two method report() and render(), both has their own responsibility.
The report method is used to log exceptions. By default, the report method passes the exception to the base class where the exception is logged. However, you are free to log exceptions however you wish. For example, if you need to report different types of exceptions in different ways, you may use the PHP instanceof comparison operator
The render method is responsible for converting a given exception into an HTTP response that should be sent back to the browser. By default, the exception is passed to the base class which generates a response for you. However, you are free to check the exception type or return your own custom response.
As in your case you want to return custom message for exception, inside render() you may use the PHP instanceof comparison operator and return you own logic.
Example :
if($exception instanceof PostTooLargeException || $exception instanceof FileException){
return response()->json([
'error' => true,
'error_message' => "The file you are trying to upload exceeds the maximum limit. Please try to upload a smaller file."
],200);
}
Go through https://laravel.com/docs/5.6/errors for more datails

custom error page - can't get into handler

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.

Manage the errors of a framework

I'm trying to develop a personal MVC framework for learning purposes. But every time I'm stuck in this problem: errors.
I feel like I'm handling them very bad. Currently I have an exception system (everything is converted to exception, even PHP triggered errors) that is catch in a try{} block that contains every line of code of the framework and the user application.
I'm treating errors such as "controller not found" or "action not found" like any other, for example "unable to connect to the database". But I feel like the latter is somehow more an "exception" rather than a pretty common "controller not found (404)".
Also currently I'm using an error handling that pretty much copy the way MVC works in my framework, in the sense that when an error occurs I load a specific action and load a specific view file for each type of error. I'm not using the MVC (by MVC I mean all the mechanism that load a controller, run an action, load a model and views for the user application) of my framework because an error in the MVC could cause an error to be triggered, which would try to manage it with the MVC which would trigger the same error again and then the MVC to be loaded again and so on in an infinite loop.
How should I handle every error of my framework? What are the best practice right now?
The execution of controller IMHO can generate two exceptions:
not found: when controller or method is missing
permission denied: when ACL blocked access
To handle this, i would just go with something like following code. And you can use multiple catch block.
try
{
$controller->$command($request, $response);
}
catch(AccessDeniedException $e)
{
$controller = new ErrorController;
$controller->accessDenied($request, $response);
}
catch(NotFoundException $e)
{
$controller = new ErrorController;
$controller->notFound($request, $response);
}
You can let AccessDeniedException to bubble up from Model Layer too, but usually it is a bad practice. Exception should be handles within same level of abstraction, where it was thrown, or, in case of critical exceptions (when object itself is unable to deal with it), the exceptions might penetrate ONE abstraction boundary. And exceptions should NOT leave the Model Layer, instead they should create error state in the layer, and be processed in your current View instance.
The point is this: instead of magical handler for all errors, you should handle errors close to the place where it originated.
You can do something like a more proper message at the try catch. For example:
try
{
//Your code here
}
catch (Exception $e)
{
// Clean the output buffer if one exists
ob_get_level() and ob_clean();
// Display the exception text
echo sprintf('%s [ %s ]: %s ~ %s [ %d ]', get_class($e), $e->getCode(), strip_tags($e->getMessage()), $e->getFile(), $e->getLine())."\n";
// Exit with an error status
exit(1);
}

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