Elliptical view
Elliptical view

Reputation: 3782

Debugging PRG in php - how to get errors to show?

How does one get php to stop on a non-fatal error inside a PRG (POST-Redirect-GET) segment, so you can see the error message, without the subsequent header() used for the redirect wiping out the error message?

Example Caller.htm

<form method="post" action="Callee.php">
    <input type="text"   name="PostData" />
    <input type="submit" value="Go"      />
</form>

Example Callee.php:

<?php
// POST section:
if($_POST) {

   $var = $x; // non-fatal error: $x is missing.

   header("Location: ". $_SERVER['REQUEST_URI']. 'Query'); die; // Redirect & GET
}
// GET section
// ...

What happens is that when testing, php reports the error for the missing $x, but then keeps moving, hits the header() and discards the error output, so you never see the error message on your screen.

You can temporarily put a die; (or exit;) just before the header, or comment out the header to test the code. Then when the code is working take out the die; or put the header back in. But this doesn't work very well in development as I've found a number of times an error crept in that I didn't even know was there.

Sometimes you can move the header up above where the errors are likely to occur. However, in the more general case one needs to be able to pass a query string to the GET section, so the header must be at the bottom of the POST section.

I think this might be what php calls an E_WARNING, "Run-time warnings (non-fatal errors). Execution of the script is not halted.", but I'm not sure.

I'm running 5.4.23:

error_reporting = E_ALL | E_STRICT
display_errors = "On"                           
log_errors = "On"
ignore_repeated_errors = "Off"

[All that I tried deleted. Jack has the answer below.]

Upvotes: 3

Views: 123

Answers (2)

Ja͢ck
Ja͢ck

Reputation: 173562

First of all, you should assume things go right, so the redirect should take place inside the try scope:

if($_POST) {
     try{

        $var = $x; //BAD CODE, $x is missing.

        header("Location: ". $_SERVER['REQUEST_URI']); // Redirect & GET
     } catch (Exception $e) {
        echo $e->getMessage();
     }
     exit;
}

Now, if you want your code to throw exceptions on warnings and notices, have a look at ErrorException and define a custom error handler that turns them into exceptions:

function exception_error_handler($errno, $errstr, $errfile, $errline ) 
{
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}

set_error_handler("exception_error_handler");

Above code is taken from the documentation.

Preferably, you will want to use an error logger (related question):

        // ...
     } catch (Exception $e) {
        $logger->fatal($e); // or $this->fatal($e);
     }

Putting it together

function exception_error_handler($errno, $errstr, $errfile, $errline ) 
{
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}

set_error_handler("exception_error_handler");

if($_POST) {
     try{

        $var = $x; //BAD CODE, $x is missing.

        header("Location: ". $_SERVER['REQUEST_URI']); // Redirect & GET
     } catch (Exception $e) {
        echo $e->getMessage(); // or log the exception
     }
     exit;
}

Upvotes: 2

Try echo your input;

echo $_SERVER['REQUEST_URI']; You can see if your input is empty: before being redirected by header();

Upvotes: 0

Related Questions