How to catch require_once/include_once exception? - php

I'm trying to write code similar this:
<?php
$includes = array(
'non_existing_file.php', //This file doesn't exist.
);
foreach ($includes as $include) {
try {
require_once "$include";
} catch (Exception $e) {
$message = $e->getMessage();
echo "
<strong>
<font color=\"red\">
A error ocurred when trying to include '$include'.
Error message: $message
</font>
</strong>
";
}
}
I'd tried require_once and include_once, but try catch doesn't catch the exception.
How could I catch this fatal errors/warning exceptions?

Since include/require does not throw an exception, check before if the file your want to include exists and is readable. eg:
$inc = 'path/to/my/include/file.php';
if (file_exists($inc) && is_readable($inc)) {
include $inc;
} else {
throw new Exception('Include file does not exists or is not readable.');
}

These functions are throwing E_COMPILE_ERROR, and are not catchable like this.
To handle these errors see set_error_handler.

This solution (adapted from here) worked fine to me:
register_shutdown_function('errorHandler');
function errorHandler() {
$error = error_get_last();
$type = $error['type'];
$message = $error['message'];
if ($type == 64 && !empty($message)) {
echo "
<strong>
<font color=\"red\">
Fatal error captured:
</font>
</strong>
";
echo "<pre>";
print_r($error);
echo "</pre>";
}
}

Related

How to put proper error handling on include php file

I'm linking a php file but I want to be handle it when it errors and notify the user, is this the proper way of error handling of include? Or is it too long? What is the better way?
<?php
try{
if ((include 'File.php') == TRUE){
}
else{
throw new Exception('Error loading the Parent Page: File.php ');
}
}
catch(Exception $e){
echo 'Message: ' .$e->getMessage(). ' Return to HomePage';
}
Just remove the if-statement and use require_once('File.php'); inside your try-catch-block.
Now change your Exception to Throwable and it should work.
<?php
try{
require_once('File.php');
} catch(Throwable $e) {
echo 'Message: ' .$e->getMessage(). ' Return to HomePage';
}
To check if the file exists, use:
if(file_exists('File.php')){
require_once('File.php');
}else {
echo "File not found";
}
It's good to use if-else block for checking whether you can include or require a file in the flow like this.
if( ! file_exists( 'File.php' )){
echo 'File does not exist' . 'Return to HomePage';
}
else{
require_once 'File.php';
}

How to check if included file from a loop comes with errors

I have this kind of loop. On each iteration it should include a file, Included files can come with errors. Once some of included files gets an error the whole process of getting lost. How to prevent breaking of the process?
I tried this try catch but it errors from included files still cause stopping execution of file.
Thanks
foreach ($li_arrays as $index => $li_array) {
if($index == 0){
try {
require 'update.php';
} catch(Exception $e) {
echo "Exception caught with message: " . $e->getMessage() . "\n";
}
}
elseif ($index == 1){
try {
require 'update1.php';
} catch(Exception $e) {
echo "Exception caught with message: " . $e->getMessage() . "\n";
}
}else{
try {
require 'update2.php';
} catch(Exception $e) {
echo "Exception caught with message: " . $e->getMessage() . "\n";
}
}
Errors in php are not recoverable, so they will always lead to the termination of your script.
I am not even sure that you are even talking about Errors, though if you are, this is the answer to your question.
Another thing to be aware of:
Require will throw an E_COMPILE_ERROR if the required file doesn't exist, which is also something you won't be able to catch.
If you don't want to terminate if the script isn't found, use include instead.
At the end I changed "require" with "include" and used this try-catch approach inside each included file.
$attempts = 0;
do {
try
{
////PHP code ///
} catch (Exception $e) {
echo "\n\n======EXCEPTION======\n\n";
var_dump($e);
$attempts++;
sleep(30);
continue;
}
break;
} while($attempts < 5);

Fatal error catched by register_shutdown_function and update json_encode

I can catch a fatal error with register_shutdown_function('shutdown')
function shutdown(){
$error = error_get_last();
$result['message'] = $error['message'];
}
and I have an echo json_encode($result);
Unfortunately this echo json_encode shows nothing because json is not updated with the message of the fatal error.
What can I do to fix this?
Why move one array to another array and then echo the second array.
Why not just do this
function shutdown(){
$error = error_get_last();
echo json_encode($error);
}
Or even this
function shutdown(){
echo json_encode(error_get_last());
}
Apart form the use of an unnecessary array, this will give you all the information available from get_last_error()
Of course it could be that the error_get_last() information is just not available at this late stage in the shutdown process. If this is the case then you can pass extra parameters to the shutdown function and this may be what you need to do.
register_shutdown_function('shutdown', get_last_error());
and
function shutdown($last_error){
echo json_encode($last_error);
}
EDITED:
First I have added error_reporting(~E_ERROR); // don't report fatal errors
The first one worked for me I mean
error_reporting(~E_ERROR); // don't report fatal
register_shutdown_function('shutdown');
function shutdown(){
$error = error_get_last();
if ($error['type'] === 1){
echo json_encode($error);
}
For my needs I wrote:
function shutdown(){
$error = error_get_last();
if ($error['type'] === 1){ // 1 means fatal error
$res['message'] = $error['message'];
$res['success'] = true;
header('Content-Type: application/json');
echo json_encode($res);
}
}

Well readable error?

If i have a c1.php
<?php
class C1 {
function f1($value) {
if($value == 'ok') {
echo "OK!";
} else {
throw new Exception("WRONG!");
}
}
}
?>
and index.php
<?php
require_once('c1.php');
$c = new C1();
$c->f1('ok');
$c->f1('asd');
?>
Can anybody know, how to construct a well readable error message like "Error: you have wrong value in C:\xampp\htdocs\projekt\index.php: line 5" instead of tracktracing
OK!
Fatal error: Uncaught exception 'Exception' with message 'WRONG!' in
C:\xampp\htdocs\projekt\c1.php:7 Stack trace: #0
C:\xampp\htdocs\projekt\index.php(5): C1->f1('asd') #1 {main} thrown in
C:\xampp\htdocs\projekt\c1.php on line 7
that reading is a little difficult.
Catch the exception. This is the point of exceptions.. they are catchable and you can do something with the information (for instance.. output just the message).
You can do something like this:
try {
$c = new C1();
$c->f1('ok');
$c->f1('asd');
} catch(Exception $e) {
echo 'Error: you have wrong value in ', $e->getFile(), ' on line ', $e->getLine();
// ... code
}
i caught it
try {
..
} catch(Exception $e) {
//echo $e->getTraceAsString();
$t = $e->getTrace();
$t = $t[0];
echo 'Error: file - ',$t['file'],' - line: ',$t['line'],
' - function: ',$t['function'],'; ',$e->getMessage();
}
thank you for hints.
Simple, don't use an exception. They should be used when you're doing a try-catch or for an exceptional situation. This is not exceptional - meaning nothing can possibly turn an error with just a if-else statement.
So just echo out the error message of your choice.

Try Catch cannot work with require_once in PHP?

I can't do something like this ?
try {
require_once( '/includes/functions.php' );
}
catch(Exception $e) {
echo "Message : " . $e->getMessage();
echo "Code : " . $e->getCode();
}
No error is echoed, server returns 500.
You can do it with include_once or file_exists:
try {
if (! #include_once( '/includes/functions.php' )) // # - to suppress warnings,
// you can also use error_reporting function for the same purpose which may be a better option
throw new Exception ('functions.php does not exist');
// or
if (!file_exists('/includes/functions.php' ))
throw new Exception ('functions.php does not exist');
else
require_once('/includes/functions.php' );
}
catch(Exception $e) {
echo "Message : " . $e->getMessage();
echo "Code : " . $e->getCode();
}
As you can read here : (emph mine)
require() is identical to include()
except upon failure it will also
produce a fatal E_COMPILE_ERROR level
error. In other words, it will halt
the script
This is about require, but that is equivalent to require_once(). This is not a catchable error.
By the way, you need to enter the absolute path, and I don't think this is right:
require_once( '/includes/functions.php' );
You might want something like this
require_once( './includes/functions.php' );
Or, if you're calling this from a subdir or from a file that is included in different dirs, you might need something like
require_once( '/var/www/yourPath/includes/functions.php' );
This should work, but it is a bit of a hack.
if(!#include_once("path/to/script.php")) {
//Logic here
}

Categories