How to manage database related exceptions in the game! 2.0 / Scala using Anorm

I am currently playing Play with game 2.0 (Scala). I have to admit, this is a lot of fun. I have a question, although it is related to database operations exceptions .

Let's say I have a Car as a domain class and that I have an integrity constraint on one of the fields, say, a model , so in db I can not have two (2) lines having the same model name:

case class Car(id: Pk[Long], name: String, model: String) 

I am trying to insert a record in the database as follows:

 def create(car: Car): Option[Long] = { DB.withConnection { implicit connection => try { SQL("insert into cars (name, model) values ({name},{model}").on("name" -> car.name, "model" -> car.model).executeInsert() } catch { case e: Exception => { Logger.debug(e.getMessage()) None } } } 

if I do not catch the exception, as in the previous code, then when I call this method from my controller with a model that has a value that already exists in the database, I get the following exception:

 com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'Enzo' for key 'model' 

Is there a way to catch a MySQLIntegrityConstraintViolationException instead of an Exception so that I have fine-grained control over what might go wrong and then provide a more compressed feed back to my user, for example (in a browser or on a mobile device)?

Is this the best way to handle database operations and exceptions, or are there any better methods that everyone uses?

thanks in advance,

+6
source share
2 answers

I think you look like something in these lines:

 import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException catch { case e:MySQLIntegrityConstraintViolationException => Logger.debug("Whoops") case e:Exception => { Logger.debug(e.getMessage()) None } } 

Important note : make sure you import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException , not com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException . More precisely, make sure that your import matches the exception in your stack trace.

As for the best practices, I don’t know how I also play with this card :).

As for user feedback ... perhaps Flash Scope is a good way to link single-line lines to the "next page" (for example, if the car was successfully saved or not). See http://www.playframework.org/documentation/2.0/ScalaSessionFlash (Scroll down to "Scope".)

+2
source

I work on a slightly different playground, but as I understand it, I solved the same problem. I work with liftweb, maven and scala 2.9.

The exception is thrown with a RuntimeException. To catch this, I catch a RuntimeException and investigate its cause. If this is a violation of the restrictions, I go about my business, otherwise I will refuse the exception. See the following code:

 import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException ... } catch { case e: RuntimeException => { e.getCause match { case cause: MySQLIntegrityConstraintViolationException => { ... } case _ => throw e } } } 

If the build fails with the following error:

 error: object mysql is not a member of package com 

check mysql package definition on maven pom. In my case, it was defined as a scope. Changing it to compile the scope allowed the assembly to succeed, and at run time this catch works correctly. Here is the mysql dependency section in maven pom.xml:

  <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.18</version> <scope>runtime</scope> </dependency> 
+1
source

Source: https://habr.com/ru/post/920624/


All Articles