Slim error handling - php

The Slim Framework is good - seriously good. One of the issues I have run into is with the way it handles errors. In vanilla PHP code I occasionally use trigger_error statements as a debug aid. In vanilla PHP this has no untoward consequences since by default trigger_errors are E_USER_NOTICE type errors that do not stop the script dead in its tracks. However, in Slim things appear to work differently. A benign trigger_error causes it to throw a wobbly and an HTTP 500 is returned.
I thought this could be corrected by
Changing the mode to development or something but the docs state that this makes no difference whatsoever to the way Slim works internally.
Next port of call - changing the slim error logging level
$app = new \Slim\Slim(array('log.level' => \Slim\Log::ERROR);
does not quite have the same effect as PHP's error_reporting. Setting it stops the error from floating up to the error.log file (the default error logger used by Slim) but crucially it does not stop the HTTP 500.
I have come across forum posts that suggest replacing the default Slim::handleErrors method. That would be easy but I wonder if that is not incorrect. What is the right way to stop Slim coming to a dead halt when it runs into a wholly innocuous trigger_error? I can well avoid this but I may rely on other code that may have such statements. I would much appreciate any help

The answer turns out to be quite simple. I figured it out by checking out the handleErrors function in slim.php. Just issue a
error_reporting(E_ALL & ~E_USER_WARNING);
prior to where the trigger_error is called and you are in business. Somewhere down the line Slim is changing the default PHP error_reporting to include E_USER_WARNING.

Related

Can I really do nothing with fatal parse errors?

Beginner question: I have done around 30 hours trying to sort out an error handler, essential as I am not a great programmer. I am 95% sure I can’t do anything about fatal-fatal errors but I am still 5% hopeful.
My error handler was working well sending out emails and text messages when it encounters problems but then I got an empty page with just:
Fatal error: Cannot use try without catch or finally
in /directory/ etc ...filename.php on line 999
(I had accidentally deleted the catch block.) The question: Someone somewhere mentioned htaccess 500 pages.
I did not understand what was described when I read it. I have done almost nothing with htaccess up to now.
Is there a way to trip some sort of static page? (I am 95% sure I can do nothing but I am stuck and still have a 5% hope and this is really important for me.) I am still running PHP 5.6 but do not want to upgrade to 7 yet. Catching these errors is far more important for me than the warnings, notices, deprecateds etc that I can catch.
Update
I saw that question and used some of the techniques there BUT it is 11 years old, huge, partly outdated and does NOT primarily address the problem I now want to solve.
I have no problem dealing with "fatal errors" such as calling a non existent function. My problem is about errors found when the script is parsed and are "unrecoverable". In my case a missing catch when a try is present.
The other answer, answers this in parts but not in ways that I can seem to use. I think there maybe a way of forcing a 500 error rather perversely by stopping error display which I will investigate soon/tomorrow. I would be grateful for 24 hours to check. I am quite happy for someone more knowledgeable to put up a better question/answer and useful info could be culled from that thread but, frankly it is a mess unsurprisingly after 11 years.
Answer - almost
Switch display_errors to off and you have a 500 error. Sadly I cannot get an .htaccess redirect to work (404 works fine). If you are good with .htaccess hopefully you will have some joy.
In some discussions there is talk of some 500 errors being "CORE" errors and REALLY unrecoverable even by .htaccess. My logs are very sparse and I cannot see any useful indication if this is the case for the catch when a try is present error.
(With a big thank you to #Dharman (if it works)). PS Will tidy this up when/if I get to the end of this.)
I don't think PHP can do anything with parse errors (or other errors during the compilation phase), but you should be able to configure your web server to display an error page of your choosing.
You don't say what web server you are using, but for example with Apache these are the Custom Error Response settings. Your errors will be HTTP 500 errors.

Changing PHP error_log behaviour possible?

I'm wondering if it's possible to change the default behaviour of PHP's error_log() functionality to include the source and originating line number by default.
I am guessing this could be potentially be done either with a PHP ini setting or by configuring apache in some specific way, though not being an apache guru I'm not sure how this would be made possible.
In my default environment, finding the source of the errors in a log generally doesn't pose too much of a problem where the error is legitimately spawned by a PHP warning or notice, as it will report automatically where the line originates... however, calls made manually by programmers to PHP error_log() don't do this, and I can't find a way to make this behavior default.
I am aware that generally speaking you can achieve the line reporting manually with the magic constant like this:
error_log("Failed to login to MySQL ".__LINE__);
However, I am curious and open to suggestions about if there are any ways to perhaps configure the way errors are reported universally in the log or anything else to get around changing every single call in code to include the magic constant.
You can define your own error handler using the set_error_handler function. This allows you to do with the errors whatever you like, as long as it is within the scope of PHP language (including printing the file and line where the error occured). Most common course of action in this case is to convert the error into a ErrorException.
Also you can use tools like xDebug, which, when activated in php.ini, display the errors in more readable form.

Is there any way around the "parse error of death"?

I'm pretty sure I'm not only one who has noticed that simple parse errors on PHP, if present in very nested scenarios (eg, an object instance which references another object instance which references another object instance that has a very tiny parse error, all of them being auto loaded) can make PHP hang forever instead of reporting the parse error and halting the execution like it would normally do — I've seen this many times and in very different code bases, always with the proper error_reporting setting set.
Is there any way around it? i.e., can it be forced to display the parse error report as it should somehow?
For the record, I'm 100% sure these hangs were caused as a result of PHP not handling the parse error correctly, as I have debugged this behaviour many times; the reason I ask is because when these hangs happen one is basically left in the dark, not even being able to tell whether PHP is acting funny or there really is an malfunctioning loop in the code somewhere — this takes time to debug, time that could be saved if, you know, PHP reported the parse error like it should.
As partially mentioned in the comments, error_reporting(E_ALL) can help display all errors. You might also have to use ini_set and make display_errors have a value of on.
Personally, I think your question is not very clear, and you should improve formatting and make it more understandable.
UPDATE: Your server / computer you're running the code on seems to be very slow. No 'hanging-around' should really occur. Or could you describe it with further detail?
Also, you might be stuck in an infinite or near-infinite loop. Check closely in your code, because unless you post all your code, this is the limit to which we can help you.
UPDATE 2: It seems that you may have mistyped the name of an object when you are trying to call it. Otherwise, it may be that you have not declared your object correctly.
Most likely one or the other.
Turns out the culprit was xdebug.collect_params, which the documentation very correctly suggests to keep disabled. Certain errors were simply generating a very large amount of data in the arguments of the call stack trace which exhausted xdebug with collect_params set to 4 and made xdebug and by extension PHP to hang, even though I have a custom exception handler in place which never actually retrieves the stack trace from xdebug, but apparently xdebug collects this data anyway.
This was hard to debug because: a) it was not straightforward to replicate b) profiling with xdebug did not help c) stepping through the code with xdebug + dbgp was not helping either d) almost no trace (no pun intended) was left other than very ocasionally logging the errors to the php error_log file and e) with a custom exception handler it was not obvious to suspect of xdebug, since I didn't involve it in the process of handling the exception, or so I thought.
So there is no such thing as the parse error of death, and I learned to never assume it's not my fault :) Hopefully this answer will help others in the future at least.

White page even with full error_reporting and display_errors

I have a really, really weird situation here. I'm working on a local development server with Zend Server installed. I have full error reporting and display errors, but I'm still getting a white page. Of course, I understand that i've done something wrong, but i want to have an idea WHAT it is i've done wrong.
The system i'm currently working on depends heavily on classes, includes and so on, therefore i can't simply "check" a page (i.e. run it standalone, outside the system, call it directly and stuff). That just won't work.
I've checked the syntax, that's not the problem. I'm stuck, and want to see my errors. If you have any ideas, please tell me!
Just to make clear, I'm already using the following:
ini_set('display_errors', true); error_reporting(-1);
After using an own error handler (php.net/set_error_handler) and some hard debugging (echo's, exits and so on), i found out that i was overruling a variable that was used later on. The variable used to be an object, but was now an int. Weird though that there wasn't any error about the fact that i was calling a function on non-object...
Very weird, but i'm glad that i've found the bug in my application.
You should be able to set the error log in your php.ini. Everything should be properly listed there. We use that approach for some of our sites, since we do not want customers to be able to see error messages on production servers.
try logging what key variables are in several of the classes. Worst case scenario, throw in some echo statements here and there just to stay sane.
error_log(print_r($var, true));

PHP - Is there a way to ignore fatal errors in php.ini/ini_settings only without modifying the code?

I inherited some PHP source code, and I have to maintain it. It has been built from scratch using no framework, just the former developer's own creation.
Now, I ask this:
Is there a way to ignore fatal errors in php.ini/ini_settings only without modifying the code?
Scenario:
SomeClass.php:
<?php class SomeClass {
...)?>
index.php:
include("SomeClass.php");
...
include("SomeClass.php");
In my development box, this throws a Fatal Error exception (because SomeClass has been declared twice), which is the obvious and expected behavior.
Here is the kicker: This source is hosted somewhere, and it works. I just don't ANY access to that server.
So I see here two scenarios:
1.) There is a way to silence this Fatal Error via 2 includes by an ini setting. This I have to know.
2.) The former developer did NOT give me the exact, updated source code that is currently up and running. I then have to insist that he give me the latest source code, but I can only do this if I am 100% sure that there is no way #1 can happen.
What do you guys think?
I tried setting a set_error_handler() function that doesn't die on fatal errors, but instead Apache crashed. In other words, PHP needs to die so that the system doesn't.
So, sorry, I really don't think there is a solution for that.
Fatal errors don't come from the include function - only warnings. You'd get fatals from require, though. Use #include and it won't even generate the warning.
Error reporting is mostly discouraged on production servers. Why let the user see if your script didn't find a file. Have a look at this http://www.php.net/manual/en/errorfunc.configuration.php#ini.display-errors and http://www.php.net/manual/en/function.set-error-handler.php. The latter could be helpful, go through the page for examples. I suggest to log errors instead of displaying it. But that will involve some sort of workaround with code.
inform your developer that he should use __autoload or spl_autoload to avoid such errors…

Categories