I doing tutorial follow http://book.cakephp.org/3.0/en/development/errors.html#exception-renderer but it is not working and display blank page.
In config/bootstrap.php
use App\Error\AppError;
$errorHandler = new AppError();
$errorHandler->register();
In src/Error/AppError.php
<?php
namespace App\Error;
use Cake\Error\BaseErrorHandler;
class AppError extends BaseErrorHandler
{
public function _displayError($error, $debug)
{
return 'There has been an error!';
}
public function _displayException($exception)
{
return 'There has been an exception!';
}
public function handleFatalError($code, $description, $file, $line)
{
return 'A fatal error has happened';
}
}
I create my_error.ctp in src/Template/Layout/my_error.ctp. And in my src/Template/Error/error404.ctp I change layout to my_error.ctp.
$this->layout = 'my_error';
Finally, In my controller
use Cake\Network\Exception\NotFoundException;
$staff = $this->Staff->find()->where(['Staff.StaffId = '=> $id, 'Staff.PartnerId = ' =>$this->partnerId])->first();
if (empty($staff)) {
throw new NotFoundException(__('Staff not found'));
}
Whenever encountering blank pages, enabled debug mode, visit the URL again, and check your error logs.
However, problem in this case is most likely that the docs are incorrect/misleading, as the example app error won't do anything at all. The _ prefixed methods are ment to be protected, having them return something has no effect, and handleFatalError is ment to return a boolean.
Just look at the source of Cake\Error\BaseErrorHandler and the core error handler Cake\Error\ErrorHandler, the methods that you are overwriting are ment to generate output!
You may want to report that as an issue over at GitHub.
If all you want to do, is create a custom 4xx error page, then all you need to do is to edit the src/Template/Error/error400.ctp template accordingly.
I found my mistake. :(
Because in bootstrap.php I copy below code at the end of file. Therefore Cake cannot understand it. Please close this issue. Thank you for support.
use App\Error\AppError;
$errorHandler = new AppError();
$errorHandler->register();
Related
I am creating website in PHP. I am using MVC in PHP. My website works like this, if user go to example.com/about then it it will load About class and index() function. If user will go to localhost/about/founder then it will load founder() function from About class. but the thing is that if I go to localhost/About or localhost/AbOut or anything like that it is loading default index() function from About class file. So what to do with case sensitivity? I mean I want my script to load index() function from class file if it is localhost/about or localhost/terms. If anything is in uppercase, then it should load 404 error function. 404 error function is already set in my site.
Please help me friends.
here is my Bootstrap.php class file
<?php
/*
Bootstrap class to run functions by URL
*/
class Bootstrap {
public $_req;
public $_body;
public $_file;
public $_error;
function __construct(){
if(empty($_GET['req'])){
require 'classes/home.php';
$this->_body = new Home();
$this->hdr($this->_body->head());
$this->_body->index();
$this->ftr();
exit();
}
$this->_req = rtrim($_GET['req'], '/');
$this->_req = explode('/', $this->_req );
$_file = 'classes/'.$this->_req[0].'.php';
if(file_exists($_file)){
require $_file;
}
else {
$this->error(404);
}
$this->_body = new $this->_req[0];
$this->hdr($this->_body->head());
if(isset($this->_req[2])){
if(method_exists($this->_req[0], $this->_req[1])){
$this->_body->{$this->_req[1]}($this->_req[2]);
}else {
$this->error(404);
}
}else {
if(isset($this->_req[1])){
if(method_exists($this->_req[0], $this->_req[1])){
$this->_body->{$this->_req[1]}();
}else {
$this->error(404);
}
}else {
$this->_body->index();
}
$this->ftr();
}
}
//this function is to set header in html code
public function hdr($var = false){
echo '<!DOCTYPE HTML><html><head>'.$var.'</head><body>';
}
//this function is tp set footer in html code
public function ftr($var = false){
echo $var.'</body></html>';
}
//error handler
public function error($var){
require 'classes/er_pg.php';
$this->_error = new Error();
$this->_error->index($var);
}
}
You shouldn't use anything to load non-lowercase URLs because of the duplicate content, and that's a good thing you're doing. The wrong URLs should fail automatically in such cases.
However, since you didn't show how are you making those calls, then only thing I can suggest at this point is to check if the called method exists (case-sensitive), and if not, throw/redirect to a 404 page (header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");).
UPDATE
After all the chat in the comments, seems like file_exists is not case-sensitive in your case, which is really weird. Hopefully someone will be able to figure it out so I can delete this (keeping it because of the info in the comments).
I solved the problem. I used this
if(ctype_lower($this->_req[0])){
$_file = 'classes/'.$this->_req[0].'.php';
and now its working. Thanx anyways friends.
I am returning Json response from zend controller.
This is my code
Controller Code
public function get()
{
$result = //calling other function and getting response in array
print("value in controller before calling toJsonModel");
print_r($result);
$temp = $this->toJsonModel($result);
var_dump($temp);
return $temp;
}
toJsonModel function
public function toJsonModel($data = array())
{
$data['requestId'] = $this->getHeader('RequestId');
print("Value just before returning to controller");
print_r($data);
return new JsonModel($data);
}
Response
First and second print displays correct values. But after getting values from toJsonModel when I try to displays wrong values and adds some other values like "captureTo", "terminate" and "children" as protected.
I don't know why it's giving me wrong message.
Can any one guide me to right path and tell me what the problem is ?
Thanks in advance.
EDIT
I am adding new screenshot to display full message.
ERROR :
{"name":"Email Not Found","message":"No account found with this email
address.","code":404,"requestId":"12","reason":"error-controller-cannot-dispatch","display_exceptions":true,"controller":"RSMobile\Controller\ForgotPassword","controller_class":null}
I finally solved this problem.
I was throwing some error from controller whenever there is a problem. I used to throw 404 when email not found. That was causing this error.
At first i thought that this is a problem related to JSON model. But thanks to #Bilal who helped me in figuring out the problem.
When I throw 404 from controller it by default appends all these data at the end. But when i throw any error other than 404, it works.
This is because you are returning an object of JsonModel from method toJsonModel.
return new JsonModel($data);
So, every object has some properties that you can use to manipulate data. See the docs of Zend\View\Model\JsonModel here
So actually the values are not wrong but there is a way to access properties of an object.
Update
Attaching dispatch event
public function onBootstrap($e)
{
// some stuff
$eventManager = $e->getApplication()->getEventManager();
$eventManager->attach("dispatch", function($e) {
echo "Dispatch!";
});
// some stuff
}
I am using Kohana 3.3 and I read in this forum post.
It says that to prevent stack traces from being shown to the end users, I need to override Kohana_Exception::_handler() to do something different with the errors that percolate up. Does that mean overriding Kohana_Exception and adding the following function?
public static function _handler(Exception $e)
{
try
{
// Log the exception
Kohana_Exception::log($e);
// Generate the response
//instead of below line:
//$response = Kohana_Exception::response($e);
$response = //what do I do here, return a 404 page or custom 500 page?
return $response;
}
//rest of function
}
If so, what do I return there?
EDIT:
bootstrap.php
/**
* Attach the file write to logging. Multiple writers are supported.
*/
Kohana::$log->attach(new Log_File(APPPATH.'logs'));
/**
* Attach a file reader to config. Multiple readers are supported.
*/
Kohana::$config->attach(new Config_File);
/**
* Attach customer error handler if we are in production
*/
if(Kohana::$environment == Kohana::PRODUCTION || Kohana::$environment == Kohana::STAGING)
{
set_exception_handler(array('My_Exception', 'handler'));
throw new Exception('text'); //this works, if removed however my exception handler does not do anything
}
My_Exception.php (in classes/My/Exception.php)
<?php
class My_Exception extends Kohana_Exception
{
public static function handler(Exception $e)
{
try
{
// Log the exception
Kohana_Exception::log($e);
// Let's try and load an error View
$class = get_class($e);
if($class == 'HTTP_Exception_404')
{
$view = View::factory('errors/404');
$view->set('error_code', 404);
}
else
{
$view = View::factory('errors/general');
$view->set('error_code', $e->getCode()); // alternatively use $e->getCode()
$view->set('error_message', $e->getMessage()); // alternatively use $e->getMessage();
}
// Let's render the output and send it to the browser
$response = $view->render();
echo $response;
}
catch (Exception $e)
{
/**
* Things are going *really* badly for us, We now have no choice
* but to bail. Hard.
*/
// Clean the output buffer if one exists
ob_get_level() AND ob_clean();
// Set the Status code to 500, and Content-Type to text/plain.
header('Content-Type: text/plain; charset='.Kohana::$charset, TRUE, 500);
// This will output the Exceptiones error message
// You may want to display something else
echo $e->getMessage();
exit(1);
}
}
}
I have actually investigated quite a bit further this issue and rewritten my asnwer from scratch now that I have a more complete understanding of Kohana's behaviour in this area.
To achieve what you're after you need to do two things:
Change the default error View (in APPPATH/bootstrap.php):
/**
* Change default error View
*/
if(Kohana::$environment == Kohana::PRODUCTION || Kohana::$environment == Kohana::STAGING)
{
Kohana_Exception::$error_view = 'errors/general';
}
Note that your template file has to use the same (and only those) variable names as Kohana's native one, i.e.:
$class
$code
$message
$file
$line
$trace
2. Create custom HTTP error pages following the tutorial you linked to in the comments.
By following these steps you assure that:
You have your own view for all Kohana's error pages.
You can have custom views for different HTTP errors.
You don't have to override Kohana's default Exception Handler (which, as this exercise proved, isn't exactly simple to implement).
I have tested the above approach and it worked like a charm for me.
I just set the Kohana_Exception::$error_view at the bootstrap file, and created the corresponding view, nothing else was necessary, all errors have redirected auto-magically...
so... I basically follow the practical symfony book, and encountered following problem.
I have properly (i guess) installed sfGuardPlugin, built the models, sqls etc, created user and tried to log in with the username and password entered.
i got the following error message:
Fatal error: Call to undefined method sfGuardUserPeer::retrieveByUsername() in /***/plugins/sfGuardPlugin/lib/validator/sfGuardValidatorUser.class.php on line 53
it looks quite weird to me, because the problematic part of sfGuardValidatorUser class looks like this:
// user exists?
if ($user = sfGuardUserPeer::retrieveByUsername($username))
{
// password is ok?
if ($user->getIsActive() && $user->checkPassword($password))
{
return array_merge($values, array('user' => $user));
}
}
while sfGuardUserPeer has just the empty class:
class sfGuardUserPeer extends PluginsfGuardUserPeer
{
}
that extends PluginsfGuardUserPeer, so i checked it out too:
class PluginsfGuardUserPeer extends BasesfGuardUserPeer
{
public static function retrieveByUsername($username, $isActive = true)
{
$c = new Criteria();
$c->add(self::USERNAME, $username);
$c->add(self::IS_ACTIVE, $isActive);
return self::doSelectOne($c);
}
}
that's the missing function!
so - what is wrong? why doesn't it work?
i have already tried all the solutions found with google, but none of them work :/
finally found it!
the
symfony propel:build-model
task unnecessarily generated the sfGuard classes in the model directory from the schema file located in the plugin directory, while all the classes were already present in the sfGuard folder.
geez, that shouldn't happen in such a well-developed framework and plugin...
Simply put that
public static function retrieveByUsername($username, $isActive = true)
{
$c = new Criteria();
$c->add(self::USERNAME, $username);
$c->add(self::IS_ACTIVE, $isActive);
return self::doSelectOne($c);
}
Code into your sfGuardUserPeer class, this will sort out the issue, I did the same when I got this error, it worked for me..
I tried to follow the instructions here: http://kohanaframework.org/3.0/guide/kohana/tutorials/error-pages But for some reason I am unable to catch the HTTP_Exception_404 I still get a ugly error page and not my custom page.
Also when I type in the URL error/404/Message, I get a ugly Kohana HTTP 404 error message.
Here is the files structure:
modules
my
init.php
classes
controller
error_handler.php
http_response_exception.php
kohana.php
views
error.php
Code:
init.php:
<?php defined('SYSPATH') or die('No direct access');
Route::set('error', 'error/<action>(/<message>)', array('action' => '[0-9]++', 'message' => '.+'))
->defaults(array(
'controller' => 'error_handler'
));
http_response_exception.php:
<?php defined('SYSPATH') or die('No direct access');
class HTTP_Response_Exception extends Kohana_Exception {
public static function exception_handler(Exception $e)
{
if (Kohana::DEVELOPMENT === Kohana::$environment)
{
Kohana_Core::exception_handler($e);
}
else
{
Kohana::$log->add(Kohana::ERROR, Kohana::exception_text($e));
$attributes = array
(
'action' => 500,
'message' => rawurlencode($e->getMessage()),
);
if ($e instanceof HTTP_Response_Exception)
{
$attributes['action'] = $e->getCode();
}
// Error sub-request.
echo Request::factory(Route::url('error', $attributes))
->execute()
->send_headers()
->response;
}
}
}
kohana.php:
<?php defined('SYSPATH') or die('No direct script access.');
class Kohana extends Kohana_Core
{
/**
* Redirect to custom exception_handler
*/
public static function exception_handler(Exception $e)
{
Error::exception_handler($e);
}
} // End of Kohana
error_handler.php:
<?php defined('SYSPATH') or die('No direct access');
class Controller_Error_handler extends Controller {
public function before()
{
parent::before();
$this->template = View::factory('template/useradmin');
$this->template->content = View::factory('error');
$this->template->page = URL::site(rawurldecode(Request::$instance->uri));
// Internal request only!
if (Request::$instance !== Request::$current)
{
if ($message = rawurldecode($this->request->param('message')))
{
$this->template->message = $message;
}
}
else
{
$this->request->action = 404;
}
}
public function action_404()
{
$this->template->title = '404 Not Found';
// Here we check to see if a 404 came from our website. This allows the
// webmaster to find broken links and update them in a shorter amount of time.
if (isset ($_SERVER['HTTP_REFERER']) AND strstr($_SERVER['HTTP_REFERER'], $_SERVER['SERVER_NAME']) !== FALSE)
{
// Set a local flag so we can display different messages in our template.
$this->template->local = TRUE;
}
// HTTP Status code.
$this->request->status = 404;
}
public function action_503()
{
$this->template->title = 'Maintenance Mode';
$this->request->status = 503;
}
public function action_500()
{
$this->template->title = 'Internal Server Error';
$this->request->status = 500;
}
} // End of Error_handler
I really cannot see where I have done wrong. Thanks in advance for any help.
First of all, you need to make sure you are loading your module by including it in the modules section of your application/bootstrap.php file like so
Kohana::modules(array(
'my'=>MODPATH.'my'
)
);
The fact that you mentioned going directly to the url for your error handler controller triggers a 404 error makes me think your module has not been loaded.
I would also suggest a few more changes.
http_response_exception.php does not need to extend Kohana_Exception, since this class is not an exception, but an exception handler. Along those same lines, a more appropriate class name might be Exception_Handler, since the class is not representing an exception, but handling them. Secondly, because of how you've named this file, it should be located in modules/my/classes/http/response/exception.php. Other than that, the code for this class looks ok.
Similarly, because of how you've named your controller, it should be located and named a bit differently. Move it to modules/my/classes/controller/error/handler.php
Remember that underscores in a class name means a new directory, as per http://kohanaframework.org/3.2/guide/kohana/conventions
Finally, I don't think you really need to extend the Kohana_Core class here, but instead just register your own custom exception handler. You can register your custom exception handler in either your application's bootstrap file, or in your module's init file with the following generic code:
set_exception_handler(array('Exception_Handler_Class', 'handle_method'));
Here's a customer exception handler I use, which is pretty similar to yours:
<?php defined('SYSPATH') or die('No direct script access.');
class Exception_Handler {
public static function handle(Exception $e)
{
$exception_type = strtolower(get_class($e));
switch ($exception_type)
{
case 'http_exception_404':
$response = new Response;
$response->status(404);
$body = Request::factory('site/404')->execute()->body();
echo $response->body($body)->send_headers()->body();
return TRUE;
break;
default:
if (Kohana::$environment == Kohana::DEVELOPMENT)
{
return Kohana_Exception::handler($e);
}
else
{
Kohana::$log->add(Log::ERROR, Kohana_Exception::text($e));
$response = new Response;
$response->status(500);
$body = Request::factory('site/500')->execute()->body();
echo $response->body($body)->send_headers()->body();
return TRUE;
}
break;
}
}
}
You're using an outdated documentation. HTTP_Exception_404 was bundled in 3.1, and you're trying to implement a solution from 3.0.
See documentation for your version of Kohana for a solution that works.
All you need to do is set the path to a different view in your bootstrap.php add:
Kohana_Exception::$error_view = 'error/myErrorPage';
that will parse all the variables currently being parsed to the error page that lives in:
system/views/kohana/error.php
ie:
<h1>Oops [ <?= $code ?> ]</h1>
<span class="message"><?= html::chars($message) ?></span>
After a VERY LONG TIME of searching I finally found a solution to my little problem.
Here is a step by step tutorial on how to load your own custom error pages with Kohana 3.2:
Change the environment variable in the bootstrap.
Here you have multiple options:
a. Do what they say in the documentation of the bootstrap.php:
/**
* Set the environment status by the domain.
*/
if (strpos($_SERVER['HTTP_HOST'], 'kohanaphp.com') !== FALSE)
{
// We are live!
Kohana::$environment = Kohana::PRODUCTION;
// Turn off notices and strict errors
error_reporting(E_ALL ^ E_NOTICE ^ E_STRICT);
}
b. Or just add those two lines without the "if":
Kohana::$environment = Kohana::PRODUCTION;
error_reporting(E_ALL ^ E_NOTICE ^ E_STRICT);
c. I have not try this way but in the new bootstrap.php you have this code:
/**
* Set Kohana::$environment if a 'KOHANA_ENV' environment variable has been supplied.
*
* Note: If you supply an invalid environment name, a PHP warning will be thrown
* saying "Couldn't find constant Kohana::<INVALID_ENV_NAME>"
*/
if (isset($_SERVER['KOHANA_ENV']))
{
Kohana::$environment = constant('Kohana::'.strtoupper($_SERVER['KOHANA_ENV']));
}
I assume that you could just give the value "production" to "$_SERVER['KOHANA_ENV']" before those lines.
Again, like I said I haven't tried it, but it should work.
I personally just commented out those lines of codes.
2 Now you need to add a few configurations in a "ini.php" file, or in the "bootstra.php" file.
<?php defined('SYSPATH') or die('No direct script access.');
/**
* Turn errors into exceptions.
*/
Kohana::$errors = true;
/**
* Custom exception handler.
*/
restore_exception_handler();
set_exception_handler(array('Exception_Handler', 'handler'));
/**
* Error route.
*/
Route::set('error', 'error/<action>(/<message>)', array('action' => '[0-9]++', 'message' => '.+'))
->defaults(array(
'controller' => 'exception_handler'
));
This is what was missing and made it to hard. For the rest you can easily just follow Kohana3.2 documentation or you can get the module that I added to a repo in GitHub: https://github.com/jnbdz/Kohana-error
Every underscore is a directory separator in a class name. So when naming your class Http_Response_Exception, the class should be in classes/http/response/exception.php. Otherwise the class will not be found by the autoloader of Kohana.
edit
Hmm, seems like the documentation is wrong in this aspect. classes/http_response_exception.php doesn't make sense.