Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get form data on 500 error

I'm attempting to gather information when our sites encounter an internal server error. We have many applications that were never set up with proper error logging and when an issue occurs our clients don't give us the best information to work with. What I would like to do is that when a 500 happens, I would like to collect data about where the issue happened such as:

  • The page the user was on
  • Any data associated with the page ($_GET, $_POST, etc)

I've set up custom error pages on our server (IIS 7) with the following config:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <httpErrors errorMode="Custom">
            <remove statusCode="500" />
            <error statusCode="500" path="/error.php?code=500" responseMode="ExecuteURL" />
        </httpErrors>
    </system.webServer>
</configuration>

And on that page I'm just var_dump-ing $_POST and $_GET to see if anything in those gets through to the error page, but it doesn't. My goal on a 500 error would be:

  • Gather data about the page/user at time of error
  • Send email to support team about issue containing the gathered data

Is there any way to collect that data and have the custom error page see it?

error.php:

switch($ErrorCode){
    case '500':
         var_dump($_REQUEST, $_POST, $_GET);
         echo "internal server error";
         break;
}

In all cases $_POST is empty even though I submitted a form to get this error and $_GET contains this (which makes sense):

array(2) {
  ["code"]=>
  string(3) "500"
  ["500;http://icom-sbs/test_php"]=>
  string(0) ""
}

4/19 Update

I played with some ideas, and the main one being storing useful data in a session variable. I attempted to store some form data in a session variable on the test page that gives the error, but it never gets into the session. It seems like the server detects that an error will occur on the page so it never even executes any code on the page and immediately executes the error page.

like image 415
Jason Kaczmarsky Avatar asked Apr 18 '13 15:04

Jason Kaczmarsky


People also ask

How can I get 500 error information?

The list of error codes and related IIS error pages are displayed. Right-click 500, and then click Edit Feature Settings. In the Edit Error Pages Settings window, select Detailed errors.

What is an API 500 error?

The client application gets an HTTP status code of 500 with the message Internal Server Error as a response for API calls. The HTTP status code 500 is a generic error response. It means that the server encountered an unexpected condition that prevented it from fulfilling the request.

Why do we get 500 internal error?

The HyperText Transfer Protocol (HTTP) 500 Internal Server Error server error response code indicates that the server encountered an unexpected condition that prevented it from fulfilling the request. This error response is a generic "catch-all" response.


1 Answers

If your server started to interpret php file and after this 500 error occurred this means some fatal error happened in your code. It might be anything, from simple typo to execution time limit reached.

The best and only way to catch fatal errors in PHP is with register_shutdown_function. You should define it on top of your working file:

function handle_fatal() {
    $error = error_get_last(); // PHP 5.2+
    if($error !== NULL){
        $error_landing_page = '[FATAL] '.$error['message'].' in '.$error['file'].':'.$error['line'] . '<br/>GET:<br/>' . print_r($_GET, true) . '<br/>POST:<br/>' . print_r($_POST, true);
        // mail here if you need that and include $_GET, $_POST variables - this will be the last state before error occurred
        exit($error_landing_page);
    }
}

register_shutdown_function('handle_fatal');

Simple test case:

// put handling function at the very beginning
function handle_fatal() {/*...*/}
register_shutdown_function('handle_fatal');

// now do some logic
if($_GET['page'] == 'dupa'){
    $_POST['subpage'] = 1; // more and more logic
    $obj = new Dupa(); // class not found exception
}

This is what I get with my handle_fatal from example:

[FATAL] Class 'Dupa' not found in /var/www/index.php:22
GET:
Array ( [page] => dupa )
POST:
Array ( [subpage] => 1 ) 

After all you should know that catching such errors is not always best idea and you should be careful about it.

like image 59
s3m3n Avatar answered Sep 21 '22 13:09

s3m3n