HowTo make "user friendly" message when catching ConstraintViolationException

757 views
Skip to first unread message

Cyrille37

unread,
Apr 13, 2011, 9:37:19 PM4/13/11
to play-framework
Hi,
I'm still discovering Play! and after the web side, I'm now in the
data side... And with some real life data model with all constraints.

It seems the play.Validation don't care about JPA integrity, so we
have to catch them at the save() time (after validation successful).
But how to construct "friendly user" message ? we just catch some:
play.exceptions.JavaExecutionException:
org.hibernate.exception.ConstraintViolationException: could not
execute update query

Is a model has several constraints, it's seems to be a hard work to
explore inner exceptions to find the corresponding message.

Is there a class which help to construct "informational message" from
such exception ?

thanks
Cyrille

Pascal Voitot Dev

unread,
Apr 14, 2011, 2:58:47 AM4/14/11
to play-fr...@googlegroups.com
You can catch any unexpected exception and then send a message but I'm not sure this is the right way to do it..
I would say that a ConstraintViolationException is a problem between your code and your model, not between your code and your user (or you do a kind of application requiring it).
It's like a NPE, you never send friendly messages to the user when they happen. Generally, it's simply a bug you have to correct.
So it shouldn't happen and you should simply prevent the case IMO ;)

regards
Pascal


--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To post to this group, send email to play-fr...@googlegroups.com.
To unsubscribe from this group, send email to play-framewor...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/play-framework?hl=en.


cyrille giquello

unread,
Apr 14, 2011, 4:29:54 PM4/14/11
to play-fr...@googlegroups.com
2011/4/14 Pascal Voitot Dev <pascal.v...@gmail.com>

>
> You can catch any unexpected exception and then send a message but I'm not sure this is the right way to do it..
> I would say that a ConstraintViolationException is a problem between your code and your model, not between your code and your user (or you do a kind of application requiring it).
> It's like a NPE, you never send friendly messages to the user when they happen. Generally, it's simply a bug you have to correct.
> So it shouldn't happen and you should simply prevent the case IMO ;)

Hi Pascal,

I'm and not agree with you. Here I try to expose my view:

Because model's technology allows to express rules, my goal is to
write a model with its rules and write the code with its business
rules. Not to express rules in the model and have some of them
automatically managed by the Validation layer and some other managed
by hands. Finally you've got to manage yourself model rules in 2
places: model layer and presentation layer. It seems to me a old way
and a open door for bug.

I agree that we should write every rules and process for an
application, but when using a framework which try to separate concerns
in their own places I do not want to split and spread rules
everywhere.

Perhaps the best solution is to override JPA constraint annotations
which need some code in presentation layer, to make them managed by
the Validation engine. Like that when we decorate a model with some
@MinSize() or @Unique() we won't be afraid to forgot to add lines of
code in several parts of the application.

It's probably the way to get KISS and DRY code (Keep it Small &
Simple, Don’t Repeat Yourself)

I hope to been clear and not overbearing ;-)
Regards
Cyrille.

Pascal Voitot Dev

unread,
Apr 14, 2011, 5:04:50 PM4/14/11
to play-fr...@googlegroups.com
Don't worry, you're welcome :)
I'm not sure to understand exactly what you would like...
In play JPA model, you have some JPA annotations to control your business model and some Play validation annotations to control the nature of the data you want to allow in your business model.
So what do you need more ?
Do you have an example that could make understand precisely your needs?

Pascal

robfig

unread,
Apr 14, 2011, 9:54:06 PM4/14/11
to play-fr...@googlegroups.com
I agree with Pascal -- you should use Validation to enforce all of your business rules.  Enforcing things like uniqueness in SQL is a nice way to catch bugs, but you should treat it as a bug if it happens in the usual flow of your program (like a NPE on user input).

Here's a couple reasons:
- Business rules can be very complicated, and there is no way to enforce most of them in SQL.  So if you want to put all of your business rules in one place, it must be the application layer. 
- It is much more efficient to catch errors earlier.  For example, if someone gives you a three digit credit card number, you would not want to issue a request to your payment provider to try to charge their card!  You would want to validate that their card number is reasonable in javascript, so that they have instant feedback that they did something wrong instead of waiting for seconds and having to refresh the page. 
- Putting your business rules in code allows you to refactor them easily -- for example, if you have some rules about Address validation, they will be useful in many places, not just when you are trying to write an address to one table in your database. 
- It is much easier to inspect and understand business rules in your codebase than in your database.  Think of trying to understand your business rules by using "SHOW CREATE TABLE" on the relevant tables versus inspecting a shared validation routine. 
- Friendly / useful error messages are trivial to provide the user if you do your own validation, than if you try to convert SQL exceptions to user-visible error messages, as you are finding out.

Hope this helps,
Rob

Cyrille37

unread,
Apr 15, 2011, 10:48:55 AM4/15/11
to play-framework
Thanks guys to take time with me, and my brain ;-)

I finally agree with yours arguments, of course. I think my mind was /
is influenced by a specific case. Here it is :

I've got Categories which holds Values. Many models are linked
(ManyToOne) to those Category Values.
In the page where Category Values are managed, I do not want to care,
to know, which models are linked or not, the database knows that
better than me. Mostly that new models can come and link (m2o) them
self to Category Values, and the Category Values code will be out of
date.

It's why, when the user wanted to delete a Value of a Category, I
prefer to try to delete the item and wait for the the database to tell
me that it's not possible because the item is in use.

After several trials (many! trials) I found how to manage that case
with the EntityManager. The solution was to put some em().clear() at
right places and catch ConstraintException.

It's not polished yet, but this code works:
http://www.nomorepasting.com/getpaste.php?pasteid=36211

thanks again for your post (and your time!)
Best regards,
Cyrille

Pascal Voitot Dev

unread,
Apr 15, 2011, 11:11:02 AM4/15/11
to play-fr...@googlegroups.com
Sorry, I don't have time to look at your code deeply now :)
Just one quick advice : when you begin to ask yourself this kind of question concerning your model, sometimes it's time to refactor the model... but not always :D
it's up to you and your application ;)

regards
Pascal

Reply all
Reply to author
Forward
0 new messages