Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to gracefully die?

So I've just read Why to never use 'or die'.

I am more confused then ever. I am validating a complicated form and I go though many nested levels of if statements and what not and I am passing a variable to the form which is called $status which can only be 'new' or 'edit'. Then when the user submits the form to be validated again the form passes along the $status value as a hidden field ($_POST). I want to make sure that the user cannot accidentally change this so I want to catch the error should something other than 'new' or 'edit' pass though. (Although I would like to completely eliminate the possibility of the user affecting this variable in an ideal world.)

So I figured that I would use DIE() in an if statement

<nested ifs>
    Select ($status){
        Case 'edit':
            break;
        Case 'new':
            break;
        default:
            //using example from article
            trigger_error("An error that should not occur has occurred", E_USER_ERROR);
            break;
    }
</nested ifs>

I don't really understand how this is cleaner than die()? Essentially I would like to call another function which displays the user some options of what they can do at this juncture to fix the error, but I want the code to absolutely stop running as I don't want an if statement further down to continue parsing anything and generating an error when it finds something other than 'new' or 'edit'.

I'm not sure how clear I am so please feel free to ask me to elaborate on any unclear points. (or better yet, can a hidden user field get hacked? How to prevent? :P)

like image 754
Mallow Avatar asked Mar 24 '11 20:03

Mallow


2 Answers

trigger_error() triggers an error which is handled by an error handler.

With trigger_error() you can gracefully handle errors, for example:

  set_error_handler('ErrorHandler');

  function ErrorHandler($errno, $errmsg, $filename, $linenum, $vars)
  {
    print '<pre style="line-height: 2em;">';
    printf("==> Error in `%s' line %s: %s\n\n", $filename, $linenum, $errmsg);
    debug_print_backtrace();
    print '</pre>';

    exit($errno);
  }

This is a simple example, but our company website displays a friendly error page and sends me an email that I'm an idiot and messed up somewhere :-)

The advantage over die() or exit() should be clear :-)

exit() can still be used when you need to exit. For example when you generate a template, output that, and want code execution to stop. Or when you send a header('Location: ...'); header and want to make sure the execution stops ... Just don't use it for handling unexpected situations (i.e. errors).

trigger_error() also gives you a better degree of control. You can send E_USER_NOTICE when you want execution to stop but display a notice, and E_USER_ERROR when you want execution to stop.

In addition, you can write more complex error handler functions where some IP's see a error, and the rest do not ... Kindda useful for development.

Be a but careful with overly complicated error handlers though, what happens is an error occurs inside an error handler ... ? You may have seen Inception :)

like image 107
Martin Tournoij Avatar answered Sep 25 '22 04:09

Martin Tournoij


The article you linked to explains why you shouldn't use or die, as in:

$result = mysql_query($query) or die('A MySQL query occurred: ' . mysql_error());

Obviously this is a bad idea, as it could output sensitive information about your MySQL structure to a malicious user.

However, I think there is nothing wrong (and I think the writer of the article would agree with me) to use die in the way you are using it, although presenting the user with a list of options would, indeed, be the preferred way to handle this.

like image 40
Aistina Avatar answered Sep 26 '22 04:09

Aistina