includes many php-files in one pgm and catch errors - php

i call an php pgm per cronjob at different times.
the pgm includes many php-files.
each file sends or gets data from partners.
How can i handle errors in one includes pgm.
at the time, one ftp-connection in an included pgm fails so the complete script crushes.
how can i handle this ?

You should wrap code, which is possible to crash, into try/catch construction. This will throw exeption, but the script will continue to work. More here.

Need to know more about you code inorder to give you definite answer.
In general php errors isn't catchable unless you define your own error handler from which you throw exceptions your self. Using the code below makes most runtime errors catchable (as long as they arent considered fatal)
error_reporing(E_ALL);
set_error_handler(function($errno, $errstr, $errfile, $errline) {
if($errno == E_STRICT || $errno == E_DEPRECATED) {
return true;
}
throw new RuntimeException('Triggered error (code '.$errno.') with message "'.$errstr.'"');
});
Btw, You could also define your own exception handler to display triggered errors with a full stack trace when an exception isn't catched.
Notice! I would not suggest that you add this code to a production website without rigorous testing first, making sure everything still works as expected.
Edit:
I have no idea what your code looks like, but I guess you can do something like:
require 'error-handler.php'; // where you have your error handler (the code seen above)
$files_to_include = array(
'some-file.php',
'some-other-file.php',
...
);
foreach($files_to_include as $file) {
try {
include $file;
}
catch(Exception $e) {
echo "$file failed\nMessage: ".$e->getMessage()."\nTrace:\n".$e->getTraceAsString();
}
}

Related

Report PHP errors in JSON format complying with the regular content-type

I use AngularJs for a single page application and communicate with serverside PHP via JSON. The php header sets JSON, but the error reporting from php:
php_flag display_errors 1
php_flag display_startup_errors 1
php_value error_reporting 32767
is html and not matching the content-type header of the regular answer header('Content-Type: application/json;charset=utf-8');
Therefore angularjs constantly throws on php errors. Should I use multicontent types or what to do?
If you must return PHP error/exceptions to the client-side, which is not recommended (but I know, it's easier for development), you gonna need a custom error/uncaught-exception handler for PHP. This way you're able to customize how the errors/exceptions are shown.
Here's a sample code that outputs errors and uncaught exceptions as JSON objects.
// Set error handler
set_error_handler('api_error_handler');
function api_error_handler($errno, $errstr) {
return api_error($errstr, $errno, 500);
}
// Set uncaught exceptions handler
set_exception_handler('api_exception_handler');
function api_exception_handler($exception) {
return api_error($exception->getMessage(), $exception->getCode(), 500);
}
// Error/Exception helper
function api_error($error, $errno, $code) {
// In production, you might want to suppress all these verbose errors
// and throw a generic `500 Internal Error` error for all kinds of
// errors and exceptions.
if ($environment == 'production') {
$errno = 500;
$error = 'Internal Server Error!';
}
http_response_code($code);
header('Content-Type: application/json');
return json_encode([
'success' => false,
'errno' => $errno,
'error' => $error,
]);
}
But that's not all; Since user-defined error handlers are not able to handle fatal errors, fatal error messages will still be displayed. You need to disable displaying errors with a call to ini_set():
ini_set('display_errors', 0);
So how to handle fatal errors? Fatal errors can be handled on shutdown with register_shutdown_function(). In the shutdown handler, we need to get the last error information with a call to error_get_last(). So:
// Set shutdown handler
register_shutdown_function('api_fatal_error_handler');
function api_fatal_error_handler() {
$error = error_get_last();
if ($error && error_reporting() && $error['type'] === E_ERROR) {
return api_error($error['message'], E_CORE_ERROR, 500);
}
}
Then on the javascript side of things, you have to add an error callback and show the error information to the user.
After all, why not using a mature error/exception handler package instead of implementing all of these? Meet Whoops.
Why are you relying on PHP Error for your application?
If possible, provide the part of the code that raises the error.
You should never use PHP Error to stop your application, instead do a clean exit if you need to return a JSON result.
You can use the try...catch pattern or check the statement that raises the error before actually call it (e.g. check if it is possible to go on with the execution).
Have a look here:
Clean way to throw php exception through jquery/ajax and json
How handling error of json decode by try and catch
Always remember to turn off the error in your final application: they could leak a lot of information to an attacker (and, moreover, they simply look awful).

How to automatically stop any script and redirect to an error page if an error/warning/notice is uncaught

EDIT: about the linked answer above, it's similar but different, since my goal is to debug the error in the error page.
Sometimes an unexpected error is hard to debug, since the error report is printed inside strange HTML elements, like an hidden div or a option element.
Is there not a way to automatically store error objects in a global variable and redirect the script to an error page, if any uncaught error is fired? And is there a way to do this for all errors, included the ones that normally doesn't quit the script, like warnings and notices?
You do this with a custom error handler. Turning errors into exceptions is a good way and allows you very fine grained control over error handling:
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
});
You may decide for which errors to throw exceptions and which to ignore; for example you may want to ignore or just log E_NOTICEs. With a global try..catch block or a custom exception handler you can now very easily decide what to do in case of errors.
Indeed there are ways to both redirect errors to pages, log them, track them, and what not. PHP is quite flexible. The good news is you don't have to homecook such methods, frameworks are available for that, but you can also survive without these as built in error handling facilities of PHP are sufficiently usable. If configured properly, PHP will abort on errors (or warnings, you decide), log them, and even return HTTP 500 Server Error code if plugged into a web server.
You may need to configure PHP properly. It is perfectly capable of a better error handling workflow. First of all, disable error printing, this is not how well behaved applications should report errors, and at worst, helps malicious users to break their way into your systems, using printed error output. You are not the only one viewing your webpages, you know, and not all users get confused seeing these, some wait for these. This is one of the directives you can use, editing the "php.ini" file, which configures PHP; it disables mixing error output with whatever else PHP outputs as part of content generation:
display_errors = "0"
You can also set it to "stderr", which is a good thing to do when debugging scripts using command line PHP invocation, as the output will be sent to another file channel, the so called standard error.
Take now heed of the following "php.ini" directive:
log_errors = "1"
The above will have PHP log errors either to a file or using web servers error logging facilities, depending on how PHP is invoked. On UNiX systems, the log file, listing the error and its details, will reside in "/var/log/www/", for instance.
Take a good read through the PHP documentation on error handling and reporting, starting perhaps at the following page:
http://www.php.net/manual/en/book.errorfunc.php
Don't forget to read on installation configuration. And I repeat again, NEVER have PHP display errors for a public PHP script! (and yes, I am aware that you are debugging, but I can't stress this point enough these days).
Thanks to #MladenB. and deceze, I solved my problem. This is how I coded the solution:
in a config.php file, to be included in your scripts (it's better to move the functions to a personal library file):
<?php
function my_error_handler($errno, $errstr, $errfile, $errline)
{
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
function my_exception_handler($e)
{
/**
* Exception handler that pass the error object to an error page.
* This is to avoid bad displaying or hiding of error reports.
*
* #param $e Exception The exception to manage
*/
if (session_status() !== PHP_SESSION_ACTIVE)
{
session_start();
}
session_register_shutdown();
$_SESSION['error'] = $e;
header('Location: error.php');
exit();
}
set_error_handler('my_error_handler');
set_exception_handler('my_exception_handler');
in error.php:
<?php
session_start();
session_register_shutdown();
$e = $_SESSION['error'];
echo '<h2>Stack trace</h2>';
echo var_dump($e->getTrace());
throw $e;

php session_start general error handling

I'm looking for a general way to handle session_start errors, not a way to handle one specific error. There are numerous errors which can happen, such as the session directory being full, which cause a fatal error. I want a way to trap those errors and handle them cleanly, without having to write custom handlers for each possibility.
Something like this (but not this as it doesn't work):
try{
session_start();
}catch(Exception $e){
echo $e->getMessage();
}
All help appreciated, thanks in advance.
The regular PHP session functions don't throw exceptions but trigger errors. Try writing an error handler function and setting the error handler before calling session_start.
function session_error_handling_function($code, $msg, $file, $line) {
// your handling code here
}
set_error_handler('session_error_handling_function');
session_start();
restore_error_handler();
However, this is just for capturing the session errors. A better way would be to create a general error handler that creates exceptions from errors and surround code parts that may throw errors with try ... catch blocks.

PHP/MySQL: What should I use to manage errors?

I have a website built using PHP and Mysqli and I'm at the part where I should think about my error handling.
Even if I think that my code is perfect errors will appear when I release the website to the public. I found this answer that shows how I can hide the errors for the users but the developer can still see them. Though I don't know if this is really the best approach for my site. I don't want the user to see ugly error messages produced my PHP itself but that I could design my own error message depending on the error.
How should I manage these errors? Should I save them all in a database?
How do I know which errors could occurr?
PHP has in-built function to catch various types of errors:
set_error_handler
You should use this function to capture the errors across all your pages, you can write custom code whether to insert errors to database, or to write into separate error log file, or to notify immediately through email to developers, you can decide.
I would start by using
try
{
//your code here
}
catch(Exception $ex)
{
echo $ex->getMessage();
}
When doing database queries. The error handling can be loggin it to a file or something like that.
That way you catch what's happening and set yourself what needs to be done....
error_reporting(E_ALL);
ini_set('display_errors','On');
ini_set('error_log', 'error.log');
ini_set('log_errors', 'On');
These functions will show errors if any also it will list errors in error.log.
If you want to hide the errors from appearing on site then you can set value from "on" to "off".
If you want to hide it only from users and not for developers then you can set "ini_set('display_errors','off');" so these will not visible to users but developers can resolve it from error.log
How should I manage these errors?
You should record them and analyse the logs to resolve them (or at least ensure your site is secure).
Should I save them all in a database?
No - you're going to lose visibility of database connectivity issues. The right way is via the syslog functionality on the local machine.
How do I know which errors could occurr?
? All of them.
Handling errors is one of the most important aspects of an application. The users expects it to work, but when an error occurs their may loose confidence into your application, no matter who good it is. I learned it the hard way.
We use a class similar to the following:
class ErrorHandler
{
public static function registerHandlers()
{
$inst = new ErrorHandler;
set_error_handler(array(&$inst, 'errorHandler'), E_ALL);
set_exception_handler(array(&$inst, 'exceptionHandler'));
register_shutdown_function(array(&$inst, 'shutdownHandler'));
}
public function shutdownHandler()
{
if (($error = error_get_last()))
{
$this->_clearOutputBuffers();
// Handle error
}
}
public function errorHandler($errno, $errstr, $errfile, $errline, $errcontext)
{
$this->_clearOutputBuffers();
// Handle error
}
public function exceptionHandler(Exception $exception)
{
$this->_clearOutputBuffers();
// Handle error
}
private function _getErrorCode($sMessage, $sFile, $nLine, $nCode)
{
$errorCode = sprintf("%u", crc32($sMessage.$sFile.$nLine.$nCode));
}
private function _clearOutputBuffers()
{
if (count(ob_list_handlers()) > 0)
{
ob_clean();
}
}
}
This class is able to catch most errors and works surprisingly well for debugging purposes as well. When ever an error is caught we write all the information to a file that we can reference later. Further we separate our environments between development and production and have separate error screens for it.
For the development environment we use an error screen that displays the extract of the file a stack trace and variables.
For the production environment we display an error screen containing the error number returned from _getErrorCode. If a customer wants to contact us about the error, all he has to do is tell us the number and we can instantly look it up and have all the data in front of us.
I have attached a screenshot of our development error screen.

How do I manage errors with strict reporting in PHP?

I use a custom error handler with complete error reporting in PHP for tracking errors. This works great for debugging and logs all my errors in a database to investigate later.
Anyway, this method now disables the usage of # to ignore an error when one occurs. I now have the issue where I try to rename a directory on my system, because it may occasionally throw an error (if files are being accessed within it).
I would like to be able to catch this error in my code, to prevent executing the rest of the function, but I also do not want this error to appear in my error logging database (considering this error is 'managed' within the code, there is no need to see that it failed).
Is there a simple solution to this? I try using try / catch but it still appears to throw the error.
You can convert all errors/warnings/notices to exceptions
function exceptions_error_handler($severity, $message, $filename, $lineno) {
if (error_reporting() == 0) {
return;
}
if (error_reporting() & $severity) {
throw new ErrorException($message, 0, $severity, $filename, $lineno);
}
}
set_error_handler('exceptions_error_handler');
I think it is better to handle exceptions, than php native errors.
#zerkms' solution would work fine, but my error handler is already completed so to extend this to give me the functionality, I have simply included:
if ( error_reporting() == 0 )
return;
at the start of my handler. This way, if the # is used on a function, the error is still thrown, but ignored at the start of the handler (hence, not logged into the database, etc) and I will still get the boolean result from a function, such as rename().
This also still enabled me to use a try/catch solution on code if need be.

Categories