Kohana 3.2 Passing Query Variables to Index Page - php

I am trying to do something like this:
$this->request->redirect("/?message=".HTML::entities($message));
However, this is resulting in my index controller dying on me (ie 500 internal server error, no stacktrace). Is this a no no?

No stacktrace while 500 error in Kohana indicates some low level error (PHP or Web Server error). It could be object properties or method Visibility issue or something.
Otherwise Kohana would generate for you exception explanation (when errors => true is set in bootstrap.php in Kohana::init() section).
Inspect your server error log file for last errors. You'll find solution there.

public function action_index()
{
$to = arr::get($_GET,'to' , 'world');
$this->response->body('hello, '.urldecode($to).'!');
}
public function action_jump() {
$to = urlencode('Tony Stark');
$this->request->redirect('/?to=' . $to);
}

Related

500 errors are not caught in prod environment

I have a strange problem in a symfony 5.3.10 app and i can't wrap my head around it.
If I trigger a 500 error, like so:
/**
* #Route("/", name="pvr_index", methods={"GET"})
*/
public function index(): Response
{
echo $a;
Where $a is not defined, in dev environment I get a nice error page.
I'd expect that in prod I would get a not so nice error page that just tells me that i have a 500 error. And this would happen correctly until some time ago, when something changed, but I don't know what.
Now instead I get no error, not even in the symfony server console, and the script execution would keep on going like nothing happened.
What I have tried:
Adding the supposed exception inside a try/catch:
try {
echo $a;
}
catch (\Exception $e)
{
dump($e);
die();
}
Nothing happens, the catch isn't triggered.
Creating an exception listener:
In services.yaml i have:
exception_listener:
class: App\Event\ExceptionListener
tags:
- { name: kernel.event_listener, event: kernel.exception }
And in ExceptionListener.php i have:
class ExceptionListener
{
public function __construct(Environment $engine) {
$this->engine = $engine;
}
public function onKernelException(ExceptionEvent $event)
{
dd($event->getThrowable()->getMessage());
}
}
Still nothing happens, the listener isn't triggered.
Everything works as expected in dev environment, the problem presents itself only in prod.
Looking at a phpinfo(); page I see that the error reporting is enabled, so I think that the problem lies in the symfony configuration.
I'm using php 7.4 and have no real access to the php.ini file
This is not a Symfony error (nor a PHP error for that matter).
On PHP 7.4, trying to output an undefined variable would only raise a notice, not a fatal error (code 500). Notices are silently swallowed up by the engine unless you configure your server to log them or output them, where you'd get something like:
Notice: Undefined variable: a in file xxx.php line Y
A try/catch won't do anything for you, since no exception is thrown for you to catch.
Even on PHP 8 or 8.1, this will only raise a warning like:
Warning: Undefined variable $a
You can see the result under version < 8 and >= 8 here.

How Laravel handles PHP warnings?

I'm trying to connect to a LDAP server using Laravel. It is important to say that I'm using the PHP functions ldap_connect and ldap_bind instead of using a package to handle it.
The point is that when I provide wrong user and password, the ldap_bind function gives to us a PHP warning. I'm OK with this warning and, as is in the documentation, the function returns false when the bind does not occur.
But, Laravel is throwing an exception when this warning is triggered. This is not an exception, Laravel should not throw an exception and I wouldn't like to handle this as an exception; I just have to build an if condition that will return a message to the user.
Does Laravel catch all warnings as an Exception?
This is the intended behavior for Laravel. Laravel will turn any error into an ErrorException instance. Here's the bootstrap() method inside the Illuminate/Foundation/Bootstrap/HandleExceptions.php class.
public function bootstrap(Application $app)
{
$this->app = $app;
error_reporting(-1);
set_error_handler([$this, 'handleError']);
set_exception_handler([$this, 'handleException']);
register_shutdown_function([$this, 'handleShutdown']);
if (! $app->environment('testing')) {
ini_set('display_errors', 'Off');
}
}
The error_reporting(-1); will set PHP to report all errors (read more here).
While this part of code:
set_error_handler([$this, 'handleError']);
Will set a custom error handler. If you check the handleError() method, it's pretty clear that Laravel will turn any error into an ErrorException instance.
public function handleError($level, $message, $file = '', $line = 0, $context = [])
{
if (error_reporting() & $level) {
throw new ErrorException($message, 0, $level, $file, $line);
}
}
Read more about user-defined error handler here.
Hope this clear things up. :)
Not sure exactly the reason because I didn't write it but I assume having it work this way makes logging much easier.
Warnings get logged in php's error log but it's not possible to pass additional information along with it as context.
If that warning gets turned into an exception though, then you can pass the exception to the logger as well as other information such as the route which was hit, the request variables, etc... and log everything together. You also get to dictate the severity of the issue by designating it as log, debug, info, notice, warning, error, critical, alert, and emergency and through monolog, handle each of those as you see fit. This creates a log which is much easier to read and makes your code much easier to debug.
Additionally, as others have pointed out, it also allows you to do your work in try catch blocks which I believe also creates neater and cleaner code than trying to check if some variable === false

How to customize error message in cakephp

I am new in Cakephp i develop my whole website but at some point when anyone type my website name like www.example.com/controllername/action it opens correct but anyone type like www.example.com/xyz then it shows error like
Missing Controller
Error: xyzController could not be found.
Error: Create the class xyzController below in file: app/Controller/xyzController.php
<?php
class xyzController extends AppController {
}
Notice: If you want to customize this error message, create app/View/Errors/missing_controller.ctp
Stack Trace
APP/webroot/index.php line 109 → Dispatcher->dispatch(CakeRequest, CakeResponse)
the same process is apply on action like i type www.example.com/controllername/xyz then it shows error like
Notice: If you want to customize this error message, create app/View/Errors/missing_action.ctp
what i do to remove this message if i create that file in view folder then in header footer it shows undefined variable where i dynamically called variable.what i do.please suggest me,thanks in advanced.
Just create the app/View/Errors/missing_action.ctp file in the given location with your custom message and styles. Then in your appController file just write this:
function beforeRender () {
if ($this->name == 'CakeError') {
$this->layout = false;
}
}
Hope this will work for you. :)
If your site users are seeing error messages like this then it implies that you don't have debug set to 0 which it should be in production.
Make sure you have Configure::write('debug', 0); set in app/Config/core.php. Only enable debugging on a staging or local copy of your site otherwise you risk revealing error messages to users on your live site that may lead to vulnerabilities.
With debug set to 0 the errors will only get logged in your app's error.log and the user will be delivered a 404 page. This is correct as a missing Controller is technically an error.
You are getting errors like this because you're using the magic routing setup when you first install CakePHP to help you build your app. It is a good idea to consider explicitly defining all your app routes in routes.php and disabling the default routing behaviour by removing this line from the file:-
require CAKE . 'Config' . DS . 'routes.php';
If you do this you will not get any error messages for pages that do not exist, but you also will not be able to access any page that a route hasn't been defined for. This is not necessarily a bad thing, Beware the Route to Evil is a good read in regards to this.

how to make PHPUnit stop intercepting exceptions?

I am working with a internal framework where every exception is catched by an error handler and returned in a proper JSON error response, suitable for a RESTFul API.
Then I have a suite of tests, which are API tests, that are mainly testing that the API returns the proper JSON responses with the expected error codes.
For every test, the global variables are modified (and then restored) to emulate a different HTTP request. I do it that way to avoid the overload of doing cURL tests (through Guzzle or similar), and cause under the CLI environment, the code does not know the server's url.
<?php
// ... example, part of a base ApiTestCase class:
// Override globals (should be backed up by PHPUnit)
$_SERVER['REQUEST_METHOD'] = $request->method;
$_SERVER['QUERY_STRING'] = http_build_query($request->parameters);
$_SERVER['PATH_INFO'] = $request->path;
$_SERVER['REQUEST_URI'] = $request->path . ($_SERVER['QUERY_STRING'] ? '?' : '') . $_SERVER['QUERY_STRING'];
$_SERVER['REQUEST_TIME'] = time();
$_SERVER['REQUEST_TIME_FLOAT'] = microtime(true);
$_SERVER['HTTP_COOKIE'] = '';
// Set headers, cookies and parameters
foreach ($request->headers as $k => $v) {
$_SERVER['HTTP_' . strtoupper(str_replace('-', '_', trim($k)))] = $v;
}
if ($_SERVER['HTTP_COOKIE']) {
$GLOBALS['_COOKIE'] = http_parse_cookie($_SERVER['HTTP_COOKIE']);
} else {
$GLOBALS['_COOKIE'] = [];
}
$GLOBALS['_REQUEST'] = $request->parameters;
$responseBody = $app->start();
$response->httpCode = http_response_code();
$response->body = $responseBody ? #json_decode($responseBody) : null;
$response->headers = headers_list();
(I know that changing globals this way is not nice, and the framework should not rely on globals directly, but I have still to deal with legacy code.)
Then here comes the problem: when I try to test JSON error responses: PHPUnit intercepts the thrown exception (before the handler I mentioned in the beginning), so the framework has no chance to convert it to JSON and return the proper response.
I tried to find something in the PHPUnit manual to disable the PHPUnit error handler with no luck.
What could I do in this case? Thanks
Just to be clear, it sounds like we're not actually talking about catching exceptions here; we're talking about using PHP's set_error_handler() to intercept a fatal error before it terminates the program. This will deal with both errors and uncaught exceptions.
One thing you will not be able to do is let those errors and exceptions fall through to your error handler function -- as you've already found out, phpUnit does its own error handling that you can't override (because it's kinda fundamental to how phpUnit works).
What you're going to have to do is tell phpUnit what kind of exception or error you're expecting; your test will then pass or fail according to whether the error occurs. You won't be running the error handler, but in truth, you shouldn't need to; you can test function that separately if you need to. For error conditions, you don't need to see that the error handler produces the right output every time, just that an error occurs that will trigger the handler.
For regular PHP exceptions, you can use phpUnit's #expectedException annotation above your test function, like so:
/**
* #expectedException YourExpectedExceptionClass
*/
function testThisWillThrowAnException() {
....
}
If the PHP code is expected to produce a PHP error (ie an error, not an exception), then you would use the same idea, but phpUnit provides a helper classname for the error: PHPUnit_Framework_Error. So your code would look like this:
/**
* #expectedException PHPUnit_Framework_Error
*/
function testThisWillProduceAPHPError() {
....
}
In either case, your test will pass if the expected error/exception occurs.
You can also test for specific exception messages and codes, in case the exception class itself isn't sufficient information for you to know whether the test has done what you want it to do. See the phpUnit manual page for annotations for more info.
The example above is also correct, mine only provide Exceptions as assertions and gives you knowladge of Exceptions Works.
/**
* #dataProvider fixturesProvider // its just example
*/
public function testDataIsWrong($fixtures)
{
try
{
//Some Code
$this->fail('Exception');
}
catch(Exception $ex)
{
$this->assertEquals($ex,'Exception');
}
}
This also provide in your code possibility ,that You can Test false or inncorect data and assert it is incorrect.
The only solution I implemented that solves my problem is to not delegate the exception handler the responsibility to build and send the API error responses, but catch exceptions in the top level of your application.
In the catch I have an exception-to-error-response converter that takes care of that (or re-throws the exception when convenient), so the errors that are not critical (like the ones producing HTTP 4xx responses) are not popping up in the PHPUnit tests anymore.
My PHPUnit tests are also now able to deal with PSR-7 HTTP Response objects, instead of capturing the output buffer.

Cakephp 2 errors on reporting level 0

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 ;-)

Categories