Simply stop script execution upon notice/warning - php

How may arrange that script execution stops upon notice/warning, without changing other behaviour, inc, the notice/warning messages, i.e. e.g. not throwing an exception.
Stop script execution upon notice/warning is a different question.

You can create a custom error handling function, like so:
<?php
// error handler function
function myErrorHandler($errno, $errstr, $errfile, $errline)
{
if (!(error_reporting() & $errno)) {
// This error code is not included in error_reporting
return;
}
switch ($errno) {
case E_USER_ERROR: exit('Im a user error.');
case E_USER_WARNING: exit('Im a user warning');
case E_USER_NOTICE:
printNotice($errno, $errstr, $errfile, $errline);
break;
default: exit('Unknown Error');
}
// don't execute PHP internal error handler
return true;
}
function printNotice($errno, $errstr, $errfile, $errline)
{
// use the following vars to output the original error
var_dump($errno, $errstr, $errfile, $errline);
exit;
}
Important are the constants: E_USER_NOTICE and E_USER_WARNING.
The function printNotice() shows how you can print the original error,
so that it appears unmodified and then stops script execution with exit.
All the original error data (message, line number, etc.) is in the variables
$errno, $errstr, $errfile, $errline. PHP makes the error data automatically available at the registered errorhandler (here myErrorHandler).
In this example i'm forwarding all the parameters a second time, to printNotice() function, which could format the error differently or do what you like upon it.
And then register it with set_error_handler(), like so:
<?php
// register your error handler
set_error_handler('myErrorHandler');
In order to test the error handling you might use the function trigger_error():
trigger_error("This is a User Error", E_USER_ERROR);
trigger_error("This is a User Warning", E_USER_WARNING);
trigger_error("This is a User Warning", E_USER_NOTICE);

Straight forward answer to your question is NO you can't.
You have to create a custom error handler that stops execution.
As there is no way to do this outside.

Related

PHP "ERROR! [2] ... Only arrays and Traversables can be unpacked" not reaching set_error_handler() callback

I am trying a set_error_handler() on this error to throw an exception but it seems not to work.I see no error code.
I am trying not to display it to the user.
if(!$this->checkBindParams($t, ...$p)){
$this->errorHandle("mysqli_stmt::bind_param(): Number of elements in type definition string doesn't match number of bind variables ", TRUE);
}
...
protected function errorHandle($message, $trigger = FALSE) {
...
if($trigger){
trigger_error($message, E_USER_ERROR);
}
}
...
set_error_handler(function($errno, $errstr, $errfile, $errline) {
if ((!$this->isFatal($errno)) && ($errno != E_USER_ERROR)) {
return false;
}
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
});
I see nothing in $errno in the set_error_handler() function. But ofcourse it is not supposed to enter errorHandle(). This is just code example. I expect it to reach the set_error_handler() callback some other way though.

Do not abort response on ErrorException

I'm writing a custom error handler for Slim/3.3.0 and I'm trying to figure out if it's worth reusing the same code to handle both errors and exceptions. To do so I've defined a custom error handler to convert errors into ErrorException instances:
require __DIR__ . '/../vendor/autoload.php';
set_error_handler (function ($errno, $errstr, $errfile, $errline) {
if (!(error_reporting() & $errno)) {
return true; // Do not run built-in handler
}
throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
});
$app = new \Slim\App(['settings' => ['displayErrorDetails' => false]]);
$container = $app->getContainer();
// [...]
$container['errorHandler'] = function (Slim\Container $c) {
return new App\Handlers\Error($c->logger, $c['settings']['displayErrorDetails']);
};
I can then log uncaught exceptions and/or display my generic "There was an error" page to my liking (so far so good).
But now I want to handle minor issues (E_WARNING, E_NOTICE, etc.) differently: instead of aborting everything and showing the generic error page template, I want to be able to continue execution and/or display the error message inline (just like PHP does by default) and here's where I'm lost. The display inline part is easy but my scripts aborts right there:
namespace App\Handlers;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
final class Error extends \Slim\Handlers\Error
{
public function __invoke(Request $request, Response $response, \Exception $e)
{
if ($this->displayErrorDetails) {
$response->write($e);
} else {
$this->saveToLog($e);
$response->write('[ERROR]');
}
if ($this->isFatal($e)) {
// Aborts scripts and displays error page (OK)
return parent::__invoke($request, $response, $e);
} else {
// Seems to abort script (nothing else is shown from this poing)
return $response;
}
}
}
... testing it this way:
$app->get('/warning-test', function (Request $request, Response $response) {
$this->logger->info("Loading {$_SERVER['REQUEST_URI']}");
$response->write('<h1>Warning test page</h1>');
$response->write('<p>About to generate a warning:</p>');
$this->logger->info("Generating warning...");
1/0;
$this->logger->info("Warning generated");
$response->write('<p>This should display as well.</p>');
// ... but it doesn't. Probably because Response is immutable and my copy
// was superseded by a clone
return $response;
});
What are my options?
The set_error_handler() function takes as second parameter the error type therefore you can specify that only E_ERROR should use your custom error handler:
$errorTypes = E_ERROR;
set_error_handler (function ($errno, $errstr, $errfile, $errline) {
if (!(error_reporting() & $errno)) {
return true; // Do not run built-in handler
}
throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
}, $errorTypes);
When you want handle notices and warnings by yourself, you cannot throw an Exception as it basically cancels the normal route and only take the error response. You can do this without throwing an Exception like so:
$errorTypes = E_WARNING | E_NOTICE;
set_error_handler (function ($errno, $errstr, $errfile, $errline) {
if (!(error_reporting() & $errno)) {
return true; // Do not run built-in handler
}
\App\Handlers\Error::setNoticeOrWarning($errno, $errstr, $errfile, $errline);
}, $errorTypes);
Then you can check this later in middleware and display this.

Exit execution on calling disabled function [duplicate]

Normally php script continues to run after E_NOTICE, is there a way to elevate this to fatal error in context of a function, that is I need only to exit on notice only in my functions but not on core php functions, that is globally.
You could create a custom error handler to catch E_NOTICEs.
This is untested but should go into the right direction:
function myErrorHandler($errno, $errstr, $errfile, $errline)
{
if ($errno == E_USER_NOTICE)
die ("Fatal notice");
else
return false; // Leave everything else to PHP's error handling
}
then, set it as the new custom error handler using set_error_handler() when entering your function, and restore PHP's error handler when leaving it:
function some_function()
{
// Set your error handler
$old_error_handler = set_error_handler("myErrorHandler");
... do your stuff ....
// Restore old error handler
set_error_handler($old_error_handler);
}
You use a custom error handler using set_error_handler()
<?php
function myErrorHandler($errno, $errstr, $errfile, $errline) {
if ($errno == E_USER_NOTICE) {
die("Died on user notice!! Error: {$errstr} on {$errfile}:{$errline}");
}
return false; //Will trigger PHP's default handler if reaches this point.
}
set_error_handler('myErrorHandler');
trigger_error('This is a E_USER_NOTICE level error.');
echo "This will never be executed.";
?>
Working Example

PHP Error Logs + Add a Session Value to the log entry

This is most likely a silly question so I have no issues with it being closed etc.
I'm debugging PHP error logs and it would be of great advantage if I could see the user that created the specific error.
The userid is keep in the session.
Is it possible to customize PHP error logs to include a session value for debugging?
thx
Of course it is possible, I don't see why not:
try {
//some code
} catch (Exception $e) {
session_start();
$log = 'Caught exception: '. $e->getMessage(). "\n";
$log .= 'By user = '.$_SESSION['user_id']. "\n";
error_log($log);
}
To change error messages into Exception use this code:
<?php
function exception_error_handler($errno, $errstr, $errfile, $errline ) {
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
set_error_handler("exception_error_handler");
/* Trigger exception */
strpos();
?>
ErrorException

how to make php exit on E_NOTICE?

Normally php script continues to run after E_NOTICE, is there a way to elevate this to fatal error in context of a function, that is I need only to exit on notice only in my functions but not on core php functions, that is globally.
You could create a custom error handler to catch E_NOTICEs.
This is untested but should go into the right direction:
function myErrorHandler($errno, $errstr, $errfile, $errline)
{
if ($errno == E_USER_NOTICE)
die ("Fatal notice");
else
return false; // Leave everything else to PHP's error handling
}
then, set it as the new custom error handler using set_error_handler() when entering your function, and restore PHP's error handler when leaving it:
function some_function()
{
// Set your error handler
$old_error_handler = set_error_handler("myErrorHandler");
... do your stuff ....
// Restore old error handler
set_error_handler($old_error_handler);
}
You use a custom error handler using set_error_handler()
<?php
function myErrorHandler($errno, $errstr, $errfile, $errline) {
if ($errno == E_USER_NOTICE) {
die("Died on user notice!! Error: {$errstr} on {$errfile}:{$errline}");
}
return false; //Will trigger PHP's default handler if reaches this point.
}
set_error_handler('myErrorHandler');
trigger_error('This is a E_USER_NOTICE level error.');
echo "This will never be executed.";
?>
Working Example

Categories