Should exceptions be used for form validation? - php

This might be a n00bish question, but whatever. Is okay to use exceptions for form validation? Let's say I have a form which asks users for their name and email, is right to do the following?
try {
if (empty($_POST["name"])) {
throw new UserRegistrationException("Your name cannot be empty.");
}
if (filter_var($_POST["email"])) {
throw new UserRegistrationException("Invalid email");
}
// Save new user into database
} catch (UserRegistrationException $e) {
// Show errors on screen
}
Also -if this is in fact the correct way to do it- if the user submits both an empty name and an invalid email, would both of the exceptions execute or only the one that appears first (the name one in this case)?
I'm using PHP by the way.

I personally like to use exceptions for anything that should stop or alter program flow. In other words, if validation of a particular field changes how data is processed, or requires the process to be repeated, then I always use exception for error handling.
If it's trivial, or I'm simply compiling a list of error messages, then I do not trigger exceptions.
To answer questions, two exceptions cannot be thrown at the same time. The first throw statement that is reached will be thrown. That's not to say that sometimes it doesn't make sense to rethrow as another type of exception.

The use case for exceptions is for exceptional conditions. In this case, do you expect the username and password fields to be blank? If you're displaying a web form, I'd argue that, yes, you do expect blank username and password fields, and so you should be checking for that condition explicitly, rather than throwing an exception.
To answer your specific question, both exceptions will not be thrown if an error is encountered. The throw statement will send the program into the catch block. From there control will flow as normal.

Related

How do I get the last mysqli query executed before an exception occurs in PHP?

Here is some sample code:
try
{
$db->query($sql_q1);
$db->query($sql_q2);
$db->query($sql_q3);
}
catch (Exception $e)
{
echo $e->getMessage();
}
How can I see which query caused the error in catch so I can see it along with the error message? And a line number won't work do me, because my queries are often dynamically built.
Well, first of all, just like Usman Munir said, if you won't catch it, there will be more information than if you catch. Just try to remove that try..catch stuff from your code and you will see the first 15 characters of the query.
But in case you need the entire query, there is a way, though not that it will give it to you right away, like a designated variable that contains specifically "last executed query", but well technically you can
There is a thing called a stack trace, intended for the exact purpose. It can show you all the calls made in your code that led to the error, including all function parameters.
Change your code to this
try
{
$db->query($sql_q1);
$db->query($sql_q2);
$db->query($sql_q3);
}
catch (Exception $e)
{
var_dump($e->getTrace());
// or to get the full error info, just
var_dump($e);
}
and you will see your query in the full glory, though it will be quite a pain to get the actual query automatically if that's your goal. but if you want to just log/visually inspect the error information, it will do.
Not that obviously you should never put var_dump() inside try_catch() in any real life code. Instead, some handling code must be put into your error handler. Especially if your purpose is debugging. Hence, your real life code should be rather this
// somewhere in the bootstrap
include 'error_handler.php';
// anywhere in your code
$db->query($sql_q1);
$db->query($sql_q2);
$db->query($sql_q3);
and in the error_handler.php you can add a code to print the full stack trace. an example for such a file you can find in the article Usman Munir posted a link to (which incidentally I wrote).
Note that stack traces tend to grow really big, and can litter your logs significantly. So consider making extended output optional.
One possible solution if you are trying to know the previously executed query would be to store your SQL in a single variable and change it for each statement. Then if an error occurs with a query you can just echo out the contents of the variable. Unless there is a specific reason you need to have multiple variables to hold your queries.

catch exceptions from yodlee api

Currently I'm working with the yodlee API. As specified in the documentation the url response may throw InvalidCredentails or UserAccountLocked. I'm using PHP and I get the following response when the username or password is incorrect.
{
Error: [
{
errorDetail: "Invalid Cobrand Credentials"
}
]
}
So to check if the error occurs I want to write some code that checks if errorDetail has a value of Invalid Cobrand Credentials.
So far ok.
But the there may be so many types of errors, and each error name is different. My question is: Can I get the list of these errorDetail values
so that I can make it work without checking if the code is forcebly throwing the errors.
You can just check for the Error index and access it's value for throwing the errors. Something like this should work for you (not tested). From the repo page:
yodleeAPI.getAccounts(accessToken)
.then(function(response) {})
.catch(function(error) {});
Edit:
As far as I could tell there wasn't any exception list. So you're either going to have to go through all the exceptions manually or create a generic error message for users. I would just advice to catch the exception message and use that for the user view(if there isn't any security information in there). You can accomplish that by following the above code.
If you do feel the need to go through every exception yourself I managed to at least get the list of all methods that throw exceptions (search: exception). You'll have to go through it yourself, and parse the error message yourself. But you can find that here

Catching "die" error and paste it on the original page

So, I have a form om my webpage which insert into a database. It throws a die(mysql_error()) into a blank page if not all fields have a value. I want this error message pasted over my form, but not loose the values already inputed. I have thought about both reloading the page with a page.php?error=... and making code to check if all fields have value (which will be long and feels unnecessary since what I want is already on my screen.
Do you think something like if(field1 has no value | field2 has no value | ....){ don't do anything and do rest is the best and most effectiv?
But if I want show which field is missing aswell, it will be a LOT of code...
You don't really want to output the exact die() error message, as the user won't be able to understand it, and chances if they would understand it, they're potentially the kind of users you don't want being able to see it!
Not really sure of your situation (as you didn't post any code) but from what you've said I'd suggest using try & catch, and handling any errors that occur, for example:
try {
// perform your database query
} catch (SQLException $error_msg) { // catch the error if goes wrong
//$error_msg contains the information from the error
return 'We`re sorry, your form submission could not be handled at this time.';
}
// if we got to this stage, there were no problems
return 'success';
That way, you can verify the reasons why the Exception occured, catching the real error message so they don't see it, then returning some other output back to the user in a format that they can understand.
in all of your input fields set the html value attribute to value = <?php echo #$_POST['fieldname'] ?>
also, instead of using die, use $error = mysql_error(); and then echo $error later on

PHP using exit()

I am using Cakephp but this is a MVC/php doubt
letting the view display the message
vs
echo 'Invalid Data'; exit;
I would like to know is there any pitfalls in the second case like memory leak etc.. Which one is better
EDIT
In case of a ajax call is exit good. and what about memory leak and other issues . Are all variables deallocated
You should use a custom ExceptionHandler (set_error_handler / set_exception_handler) and throw an Exception if you encounter any errors (CakePHP should already provide an ExceptionHandler). Make some space in your view and if the ExceptionHandler/ErrorHandler has a message, show it there to let the user know.
Your second code will just produce a blank page containing the little text. Every user will appreciate if you show the message inside your usual page layout instead of producing a blank page (which looks broken to most people).
The Cake tools to signal errors to the user are session messages and error views.
For "passive" actions like view actions, you should throw a 404 or similar, possibly more specialized error, e.g. if the requested model does not exist:
function view($id) {
$data = $this->Model->read(null, $id);
if (!$data) {
$this->cakeError('error404');
}
...
}
See Error Handling with CakePHP.
For any POST action, you should return the user to the view and display an error message using $this->Session->setFlash('Error!') and appropriate error messages for each invalid form field. That's the default behavior of baked views and controllers.
Terminating the whole script with exit makes for a miserable user experience.
In general, you should avoid exit. Exit is an abnormal termination, and programs should not terminate abnormally. Even if an error occurs, there are still many things that needs to be done - cleanup, logging, notifying the user etc. After all, your operating system doesn't reboot every time it cannot open a file.
performance-wise (AJAX cals)
Use exit().
user experience-wise (standard site nav)
Show the error in a proper formated page keeping the user within your site.

Why not to use Array of errors instead of Exception Handling?

Why not using array of errors instead of throwing errors and check if it's not empty later in the code.... Exception handling is very confusing to me , I can not understand it's purpose ... can anybody enlighten me !?
they compare it with die() as better not to stop the execution of the code , why would I stop the execution of code if I don't want to !? ofcourse I do
I'm a beginner programmer , it might be confusing to you as well , or because i'm not very experienced in this ugly thing.
Please in the context of PHP only.
One reason you might decide to throw an exception is because you can add a jump in control flow without an explicit piece of syntax. What do I mean by that?
rather than
$returnVal = doSomeDiskFunction();
if($returnVal == $ERROR_CODEA)
{
// do some stuff
}
else if( $returnVal == $ERROR_CODEB)
{
//do some stuff
}
$returnVal = doSomeOtherDiskFunction();
if($returnVal == $ERROR_CODEA)
{
// do some stuff
}
else if( $returnVal == $ERROR_CODEB)
{
//do some stuff
}
you could just have
try{
doSomeDiskFunction();
doSomeOtherDiskFunction();
}
catch(ExceptionTyepA $exceptionA)
{
//do some stuff
}
catch(ExceptionTypeB $exceptionB)
{
//do some stuff
}
Seems a lot cleaner, yes??? It's also a formal way of alerting calling code that it needs to deal with potential error conditions if you choose to have the exception propogate upwards in the call stack.
Also, exceptions should be used for code that you don't expect to happen, like failing to connect to a database, not code that you DO expect to happen, like a user submitting bad data. The other poster made the point that you kind of expect a user to make a lot of errors filling out a form, so you wouldn't throw an exception when you come across some data that is in a bad user-entered format, because you expect user data to be poor quality.
It really depends what type of error you're talking about.
I always die(); for really bad errors, like if the application couldn't connect to the database.
But for anything that takes user input, like a form, it's better to use arrays of errors that the user can see all at once, instead of correcting one field at a time and repeatedly having to press submit.
(If you want to know in more detail, I often use an array of arrays to display errors, since one field could potentially have multiple things wrong with it. For example, if a user tries to register an account with username "1337", I will use a validator to check against multiple conditions and it will return an array with things like "username must be at least 5 characters long", "username must contain at least three letters", "that username has been disallowed by the administrator" and all those messages will be displayed simultaneously above that particular field)
There is a way to code completely without exception handling. For example, if you have a method that returns the length of an object, have it return -1 if there's been an error. This is how most C API's are built.
That said, when you're building complex systems, and you have a ton of "black box" code that might behave wrongly, exceptions help. The way exceptions work is like this: when someone "throws", folks on the call stack start getting notified. One step at a time. One of these methods can "Catch" the exception and handle it.
Why is this useful: you can have a DB layer that has lots of logic inside that throws exceptions. If something goes wrong there, your DB exception handling code can fail gracefully, showing a nice error message to the user; it can also send a text message to the admin, demanding attention.
You can even create a hierarchy of exception handlers: you can re-throw the exception after you've done something with it.
PHP's exceptions sucks hard, but they still have their basics benefits:
Exception provides much more information about "What went wrong?" in much better form (exception is an object)
They make your code clearer
They are the only reasonable way to break execution of the part of code (that doesn't work as it supposes to), fix (if possible) what need to be fixed and continue without complete failure.
Really it depends on the language. C is similar in that respect -- it doesn't force you to handle an error. Most functions return -1 if they had a problem; it's up to you to check 'errno' to see what happened.
Exceptions are generally a good thing though. You rarely want to blindly continue running if an error occurred (Never never NEVER say "On Error Resume Next" in Visual Basic. Please.). It's quite easy to catch the exception and do nothing if you are sure you don't need to do anything.

Categories