We implement the majority of our business rules in the database, using stored procs.
I can never decide how best to pass data constraint violation errors from the databa
This is how I do things, though it may not be best for you:
I generally go for the pre-emptive model, though it depends a lot on your application architecture.
For me (in my environment) it makes sense to check for most errors in the middle (business objects) tier. This is where all the other business-specific logic takes place, so I try to keep as much of the rest of my logic here too. I think of the database as somewhere to persist my objects.
When it comes to validation, the easiest errors can be trapped in javascript (formatting, field lengths, etc.), though of course you never assume that those error checks took place. Those errors also get checked in the safer, more controlled world of server-side code.
Business rules (such as "you can only have so many foos per day") get checked in the server-side code, in the business object layer.
Only data rules get checked in the database (referential integrity, unique field constraints, etc.). We pre-empt checking all of these in the middle tier too, to avoid hitting the database unnecessarily.
Thus my database only protects itself against the simple, data-centric rules that it's well equipped to handle; the more variable, business-oriented rules live in the land of objects, rather than the land of records.