views:

67

answers:

2

I'm working on the back-end of my website and I'm wondering how far I should be going to test for errors and throwing exceptions accordingly? Testing in the sense of improper usage of methods and functions. Not errors under correct usage.

My biggest concern is code bloat and uglying it up with a bunch of if/elses, type checks, and other such tests.

Should you go so far as to consider every possible way someone could use an object, catch all the improper uses, and throw exceptions to make it clear to the developer using it what they've done wrong?

Or is it a better approach to let the code break naturally (obviously catching and checking for things that would be a big deal, but not for every contingency), and depend on anyone using the code to read the available documentation and use it accordingly?

Are there any general best practices or guidelines to follow when handling such issues? I'm working in PHP, is there anything specific to PHP, although this issue is generally language wide?

Thanks for any help on the matter.

+1  A: 

At least, your application should not "break" : when an error is detected (be it because you detected a problem could happen and avoided it, or because a problem did happen), you should display some nice error message, and, eventually, log the technical informations of the error.

About bloating the code : I would not put too much tests and all that in my code : it would end up in something hard to understand and maintain -- which is important !


What I generally try to do is :

  • Test for errors in the user-supplied data
    • Using a specific class, for instance, so those checks are not in the middle of the code that deals with database and business rules.
    • Those tests are relatively precise, in order to generate useful error messages for the user
      • For instance : "You should not input more than 20 characters"
      • Or "there is already a user with that e-mail address"
    • Basically, the important thing here is the user.
  • When user-supplied data seems OK, I work with it.
    • And there, if some error happens, it'll most likely be a technical error
    • Which should be logged
    • And only a "oops, an error occured" should be displayed to the user.
    • Which means that, here, tests are not as precise : we only need to know if it works or not -- not necessarily in great details.

Of course, in the end, you should ensure that the data in the DB is correct, and that you don't save only half of the data.


A common way of dealing with technical errors is using exceptions ; here is a very basic idea :

try {
    // Begin transaction to the DB

    // Some code that might fail and throw an Exception

    // Some other code that might fail and throw an Exception

    // Code here will not be executed if an Exception has been thrown

    // Commit DB transaction
} catch (Exception $e) {
    // Rollback transaction (cancels the queries that were sent to the DB)
    // Log technical informations to a file
    // Display a nice message
}

The great thing is that it allows one to place all error-handling code in a single place, and put less testing code in the middle of the important stuff ; i.e. "let it fail, we'll deal with the problems later"

Pascal MARTIN
@Pascal thanks for the answer, it's great. One thing I'd like to ask real quick though is how do you handle method call orders? -- Such as you have methods a, b, and c. You can call a>b, a>c, and a>b>c, but anything else, such as, b>a, c>a, c>a>b, etc. is not intended use and will break the code. -- Do you go out of your way to catch these mistakes and let the user know? Or do you let it break naturally and just leave them to the documentation and say, if they're not using it as documented not much I can do?
anomareh
If methods must be called in a specific order, calling them in another order should cause an error : the data will not be correct ;; in this case, well, it'll fail ;; and the developper will see that as soon as he tests his code for the first time ;; so, I'd say it's something that's not likely to happen on the production server, and wouldn't put too much code to test for it : more code means more risk of bugs.
Pascal MARTIN
+1  A: 

I usually just go as far as making sure method input parameters and/or public members are filled and of the proper type (string, int, etc...). Other than that I just let it break naturally. (If people aren't going to bother reading the documentation, they kind of deserve to have things break a little.)

As I see it, you don't bloat your code with error-checks, who's only purpose would be to support the laziness of your co-workers/clients/random-developers.

Atli
@Atli thanks for the answer, was pretty much along the lines of what I was thinking.
anomareh