When I use the built in PDO layer in TinyMVC to request records from a table, it returns the following error:
Array
Error: 0
Message: Unknown file 'register_view.php'
File:{redacted}tinymvc\sysfiles\plugins\tinymvc_view.php
Line: 125
When I however try just returning the same variable without a connection it displays it fine. The error it is raising is in the view layer because it cannot get the parameter passed to it. However I see no reason why it is doing that considering the query is running ok.
Here is the code from the view method:
<body>
<h1>Hello <?=$fname?></h1>
<p>Hello World</p>
And the code from the controller:
function index(){
$this->load->model('User_Model','user');
$this->view->assign('title','Manage your Peacock account');
$this->view->assign('fname', $this->user->fname());
$this->view->display('user_view');
}
Finally the code from the model:
public function __get($property) {
if (property_exists($this, $property)) {
/**
* Retrieve the data from the database
*/
$this->$property = $this->db->query_one('select '.$this->getTable($property).' from users where id=?',array('1'));
return $this->$property;
}
}
Any help will be appreciated
TinyMVC has the unfortunate trait of declaring an "Unknown file" error whenever a view with a fatal error is "display"ed. The reason is simple: the include code for the view is in /tinymvc/sysfiles/plugins/tinymvc_view.php in the last function - "_view()" in a "try-catch" block:
try {
include($_tmvc_filepath);
} catch (Exception $e) {
throw new Exception("Unknown file '$_tmvc_filepath'");
}
so ANY fatal error raised by the view automatically throws the "Unknown file" error.
If you want to see the real error, comment all the above lines and add the line:
require($_tmvc_filepath);
instead. This will anyways raise a fatal error if the file really isn't found, and will show you the real error that is in the view.
Related
Everything until now worked perfectly. I'm on page: http://framework.zend.com/manual/current/en/in-depth-guide/understanding-routing.html.
On this page I had to modify 3 files:
-module.config.php
-detail.phtml
-ListController.php
I get the following error:
Post Details
Post Title
Fatal error: Call to a member function getTitle() on null in C:\Program Files\xampp\htdocs\path\to\zf2-tutorial\module\Blog\view\blog\list\detail.phtml on line 6
I didn't paste the code, because it's the same from the link. Can you guys help me figure out my problem?
public function detailAction()
{
$id = $this->params()->fromRoute('id');
try {
$post = $this->postService->findPost($id);
} catch (\InvalidArgumentException $ex) {
return $this->redirect()->toRoute('blog');
}
return new ViewModel(array(
'post' => $post
));
}
Thanks for the update. Now that I see where you are in the tutorial I think you have a problem in the Mapper. See the previous page and chapter Finishing the Mapper
If your mapper cannot find an article it should throw an error as seen in that code example on line 63. Obviously your mapper returns null which causes the error you see Call to a member function getTitle() on null. Because null is not an object after all and doesn't have a getTitle() function.
So have a look at the ZendDbSqlMapper class and the find($id) method and make sure it throws an error if an id isn't found.
Inherited a piece of code where an update to a plugin has started causing this error
Fatal error: Call to a member function getId() on a non-object in...
Where the line in question is $shippingId = $order->getShippingAddress()->getId();
The update to the surrounding code, means that this function returning nothing is fine and the rest of the code can function with $shippingId not existing
What I need is a method of saying
if ($shippingId = $order->getShippingAddress()->getId() WORKS)
do_these_things()
and then instead of error'ing just carries on if not
I would do this:
if (isset($order->getShippingAddress()) && is_object($order->getShippingAddress()) ) {
/* It is an object and it isn't null */
} else {
/* It doesn't */
}
isset() checks if the expression is not null and has a value (to avoid null-pointing) and is_object() checks wether such expression is an object.
You can use the method mentioned by arielnmz or you could use custom exception handler.
try{
if ($shippingId = $order->getShippingAddress()->getId() WORKS)
do_these_things();
}
catch(Exception e){
//Echo out the error msg or save it on your error log stash. up to you
$error_msg=$e->getMessage();
}
//your regular codes
Using this way, if there is an error within the try block, the error is caught on the catch block and your code will carry on the normal execution pattern.
I'm calling a method that I know could cause an error and I'm trying to handle the error by wrapping the code in a try/catch statement...
class TestController extends Zend_Controller_Action
{
public function init()
{
// Anything here happens BEFORE the View has rendered
}
public function indexAction()
{
// Anything `echo`ed here is added to the end of the View
$model = new Application_Model_Testing('Mark', 31);
$this->view->sentence = $model->test();
$this->loadDataWhichCouldCauseError();
$this->loadView($model); // this method 'forwards' the Action onto another Controller
}
private function loadDataWhichCouldCauseError()
{
try {
$test = new Application_Model_NonExistent();
} catch (Exception $e) {
echo 'Handle the error';
}
}
private function loadView($model)
{
// Let's pretend we have loads of Models that require different Views
switch (get_class($model)) {
case 'Application_Model_Testing':
// Controller's have a `_forward` method to pass the Action onto another Controller
// The following line forwards to an `indexAction` within the `BlahController`
// It also passes some data onto the `BlahController`
$this->_forward('index', 'blah', null, array('data' => 'some data'));
break;
}
}
}
...but the problem I have is that the error isn't being handled. When viewing the application I get the following error...
( ! ) Fatal error: Class 'Application_Model_NonExistent' not found in /Library/WebServer/Documents/ZendTest/application/controllers/TestController.php on line 23
Can any one explain why this is happening and how I can get it to work?
Thanks
use
if (class_exists('Application_Model_NonExistent')) {
$test = new Application_Model_NonExistent;
} else {
echo 'class not found.';
}
like #prodigitalson said you can't catch that fatal error.
An error and an exception are not the same thing. Exceptions are thrown and meant to be caught, where errors are generally unrecoverable and triggered with http://www.php.net/manual/en/function.trigger-error.php
PHP: exceptions vs errors?
Can I try/catch a warning?
If you need to do some cleanup because of an error, you can use http://www.php.net/manual/en/function.set-error-handler.php
Thats not an exception, thats a FATAL error meaning you cant catch it like that. By definition a FATAL should not be recoverable.
Exception and Error are different things. There is an Exception class, which you are using and that $e is it's object.
You want to handle errors, check error handling in php-zend framework. But here, this is a Fatal error, you must rectify it, can not be handled.
I'm testing some legacy code that extends the default php exception object. This code prints out a custom HTML error message.
I would like to mock this exception object in such a way that when the tested code generates an exception it will just echo the basic message instead of giving me the whole HTML message.
I cannot figure out a way to do this. It seems like you can test for explicit exceptions, but you can't change in a general way the behavior of an exception, and you also can't mock up an object that extends a default php functionality. ( can't think of another example of this beyond exceptions... but it would seem to be the case )
I guess the problem is, where would you attach the mocked object?? It seems like you can't interfere with 'throw new' and this is the place that the object method is called....
Or if you could somehow use the existing phpunit exception functionality to change the exception behavior the way you want, in a general way for all your code... but this seems like it would be hacky and bad....
EDIT: here is some code to make things clearer:
class FooTest extends PHPUnit_Framework_TestCase{
public function testBar(){
include '/path/to/file.php'; //generates exception
$this->assertTrue($baz);
}
}
...
//overridden exception class
class Foo_Exception extends ErrorException{
...
so, my question, is there a way to deal with this overriden class, without doing it on a case by case basis? what if I'm not testing the behavior of the exception, just the code that causes the exception?
I would first write a test that captures the exception generation behavior:
include '/path/to/file.php'; //generates exception
public function testCatchFooException() {
try {
$this->assertTrue($baz);
}
catch (Exception $expected) {
$this->assertEquals('This is expected html from exception', $expected->getMessage());
return;
}
$this->fail('An expected Exception has not been raised Foo_Excpetion.');
}
Now you can do several things with this coverage test. You can either fix up the exception, or fix the code that causes the exception.
Another thing you can do is wrap the entire file.php in a class:
class FooClass {
function runFoo() {
include '/path/to/file.php'; //generates exception
}
}
Then add tests while using extract method until you isolate exception.
[EDIT]
Here is some serious procedural legacy code:
<?php
require_once 'helper.php'; //helper file
function countNewMessages($user_id) {
}
function countNewOrders() {
}
function countNewReturns() {
}
function getDB($init = NULL) {
}
function getDisplay() {
}
getDisplay();
?>
And here is the wrapped class:
<?php
require_once ''; //helper file
class Displayer {
function countNewMessages($user_id) {
}
function countNewOrders() {
}
function countNewReturns() {
}
function getDB($init = NULL) {
}
function getDisplay() {
}
}
?>
And now I can test it:
function testGetDisplay() {
$display = new Displayer();
$this->assertEquals('html code', $display->getDisplay());
}
And test the individual functions in it. And if I can further sprout methods on it.
The above test would be considered a coverage test. There may be bugs in it, but that is what it does. So as I sprout methods the get more code coverage from tests by sprouting that I can make sure I don't break the output.
The extened PHP exception object "prints" a costum HTML error page? You mean its error message is an entire HTML page? That's not very clever...
What you can do about it is to replace the default exception handler (see this function), call getMessage on the exception and parse the HTML error page to extract the message. Then you can print the error message and kill the script. Like this (in PHP 5.3):
set_exception_handler(
function (Exception $e) {
die(parse_html_error_page($e->getMessage()));
}
);
OK, I misunderstood the question. If the script you're testing catches the error and then echoes an error page, then this has nothing to do with exceptions. You can use the ob_ family:
ob_start();
include $file;
$contents = ob_get_contents();
if (result_is_error($contents))
die(extract_error_from_result($contents));
else
echo $contents;
ob_end_clean();
I can't seem to correctly do this, the error message of the exception just prints out, making the command line window harder to read. Below is how my code is structured and the test code.
public function availableFruits($fruit)
{
switch($fruit) {
case 'foo':
// all good
break;
case 'bar':
// all good
break;
default:
throw new Exception($fruit.' not available!');
break;
}
}
public function chooseFruit($fruit)
{
try {
availableFruits($fruit);
} catch (Exception $e) {
echo $e->getMessage();
}
}
public function testAvailableFruits()
{
$this->setExpectedException('Exception');
chooseFruit('Kiwi');
}
The error message will print out in the command line window like below. I tried all the methods shown in phpunit.de but same results.
..Error on line 13 in c:\file\path\fruits.php: Kiwi not available!.F
The error line prints out, how do I suppress that, am I doing it right at all?
I believe another way to do it is to add a comment block to the test method that looks like...
/**
* #expectedException ExpectedExceptionName
*/
Or, you can also catch the exception your self cause the method to fail if you don't get inside the catch block.
This is embarrassing as I found just the way to do it. Thanks Chris, but I tried that as well.
I tested the wrong method, chooseFruit isn't the method that throws the exception, so the exception error prints out:
public function testAvailableFruits()
{
$this->setExpectedException('Exception');
**chooseFruit('Kiwi');**
}
Testing the actual method that throws the exception will mute the error message, since it is not echoed at all:
public function testAvailableFruits()
{
$this->setExpectedException('Exception');
**availableFruits('Papaya')**
}