Say I have an SQL table that has a unique key (or other) constraint on one of the columns.
Then, I have an application (lets go ASP.NET MVC) that allows a user to edit this column.
When the user attempts to save, and the constraint is/will be broken, I need show a user-friendly error message to the user. As such, which of the following is better practice?
-
Have the application query the database to ensure the constraints are not broken, and then insert/update the row (results in two queries to the db)
OR
-
Immediately attempt to perform the insert/update, and catch the SqlException should the constraint be broken. I like this, because of only one trip to the db, however how should you then extract which index/constraint was broken and affix the appropriate message? (apart from inspecting Exception.Message?)
1 is the better all-around solution. Db calls are not the only expensive operation, exceptions are costly too. You should really only let your db throw an exception when something goes wrong due to your code, not a user action.
For example, you might later want to install Elmah and get exceptions logged and/or mailed to you. Elmah would log/mail such an exception unless you explicitly told it not to.
Plus like you said, exceptions don’t always have the most businessy information to communicate to users (especially SQL exceptions, which are SQL-specific). You have these unique and other constraints for a reason. For those reasons, validate the information before trying to store it.
Take twitter, gmail, etc. When you go to get a username, the application first checks to see if it is taken. These are uniqueness constraints at the application level, which may or may not ultimately be realized as SQL constraints. Since it is your application that faces the user, you should not try to communicate to them by translating from SQL to English.