From 4d7d4977d6e5dd8bf7005c0e51c0ae2223c7feee Mon Sep 17 00:00:00 2001 From: Sudhir Nimavat Date: Tue, 17 Jun 2025 19:23:35 +0530 Subject: [PATCH 1/3] Handle query exception 9ci/domain9#3227 --- .../gorm/tools/mango/MangoDetachedCriteria.groovy | 5 +++-- .../gorm/tools/mango/DefaultMangoQuerySpec.groovy | 10 ++++++++++ .../gorm/tools/mango/MangoDetachedCriteriaSpec.groovy | 3 --- .../groovy/gorm/tools/mango/MangoTidyMapSpec.groovy | 11 +++++++++++ 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/gorm-tools/src/main/groovy/gorm/tools/mango/MangoDetachedCriteria.groovy b/gorm-tools/src/main/groovy/gorm/tools/mango/MangoDetachedCriteria.groovy index 60c67324a..f0a8f1f79 100644 --- a/gorm-tools/src/main/groovy/gorm/tools/mango/MangoDetachedCriteria.groovy +++ b/gorm-tools/src/main/groovy/gorm/tools/mango/MangoDetachedCriteria.groovy @@ -264,7 +264,7 @@ class MangoDetachedCriteria extends DetachedCriteria { } return query.list() } - } catch (IllegalArgumentException | QueryException ex) { + } catch (IllegalArgumentException | QueryException | ClassCastException ex) { //Hibernate throws IllegalArgumentException when Antlr fails to parse query //and throws QueryException when hibernate fails to execute query throw toDataProblem(ex) @@ -319,9 +319,10 @@ class MangoDetachedCriteria extends DetachedCriteria { try { def list = hq.list(queryInfo.query, queryInfo.paramMap, args) return list as List - } catch (IllegalArgumentException | QueryException ex) { + } catch (IllegalArgumentException | QueryException | ClassCastException ex) { //Hibernate throws IllegalArgumentException when Antlr fails to parse query //and throws QueryException when hibernate fails to execute query + //of cast exception, if type of value doesnt match field type throw toDataProblem(ex) } } diff --git a/gorm-tools/src/test/groovy/gorm/tools/mango/DefaultMangoQuerySpec.groovy b/gorm-tools/src/test/groovy/gorm/tools/mango/DefaultMangoQuerySpec.groovy index 1cab69cab..8bcb2270e 100644 --- a/gorm-tools/src/test/groovy/gorm/tools/mango/DefaultMangoQuerySpec.groovy +++ b/gorm-tools/src/test/groovy/gorm/tools/mango/DefaultMangoQuerySpec.groovy @@ -192,4 +192,14 @@ class DefaultMangoQuerySpec extends Specification implements GormHibernateTest { ex.detail.contains("Text 'xxx' could not be parsed") } + void "query fails with class cast exception"() { + when: + Cust.query("location":[[address:['add 1']]]).list() + + then: + DataProblemException ex = thrown() + ex.code == 'error.query.invalid' + ex.detail.contains "java.util.ArrayList cannot be cast to class java.lang.String" + } + } diff --git a/gorm-tools/src/test/groovy/gorm/tools/mango/MangoDetachedCriteriaSpec.groovy b/gorm-tools/src/test/groovy/gorm/tools/mango/MangoDetachedCriteriaSpec.groovy index 1d2834bc7..350e78487 100644 --- a/gorm-tools/src/test/groovy/gorm/tools/mango/MangoDetachedCriteriaSpec.groovy +++ b/gorm-tools/src/test/groovy/gorm/tools/mango/MangoDetachedCriteriaSpec.groovy @@ -1,9 +1,6 @@ package gorm.tools.mango - -import gorm.tools.mango.jpql.JpqlQueryBuilder import spock.lang.Specification -import testing.Cust import yakworks.testing.gorm.model.KitchenSink import yakworks.testing.gorm.unit.GormHibernateTest diff --git a/gorm-tools/src/test/groovy/gorm/tools/mango/MangoTidyMapSpec.groovy b/gorm-tools/src/test/groovy/gorm/tools/mango/MangoTidyMapSpec.groovy index 8ee070723..b6c615347 100644 --- a/gorm-tools/src/test/groovy/gorm/tools/mango/MangoTidyMapSpec.groovy +++ b/gorm-tools/src/test/groovy/gorm/tools/mango/MangoTidyMapSpec.groovy @@ -99,6 +99,17 @@ class MangoTidyMapSpec extends Specification { ] ] + when: + mmap = tidy([ + "num": ['num1', 'num2'] + ]) + + then: + mmap == [ + num: [ + '$in': ['num1', 'num2'] + ] + ] } void "test like"() { From 8d4a34aaa01bc38891357f0c31242b31d5f650fe Mon Sep 17 00:00:00 2001 From: Sudhir Nimavat Date: Tue, 17 Jun 2025 19:46:55 +0530 Subject: [PATCH 2/3] Catch RuntimeException --- .../gorm/tools/mango/MangoDetachedCriteria.groovy | 7 ++++--- .../gorm/tools/mango/DefaultMangoQuerySpec.groovy | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/gorm-tools/src/main/groovy/gorm/tools/mango/MangoDetachedCriteria.groovy b/gorm-tools/src/main/groovy/gorm/tools/mango/MangoDetachedCriteria.groovy index f0a8f1f79..b190b11b1 100644 --- a/gorm-tools/src/main/groovy/gorm/tools/mango/MangoDetachedCriteria.groovy +++ b/gorm-tools/src/main/groovy/gorm/tools/mango/MangoDetachedCriteria.groovy @@ -264,9 +264,10 @@ class MangoDetachedCriteria extends DetachedCriteria { } return query.list() } - } catch (IllegalArgumentException | QueryException | ClassCastException ex) { + } catch (RuntimeException ex) { //Hibernate throws IllegalArgumentException when Antlr fails to parse query - //and throws QueryException when hibernate fails to execute query + //throws QueryException when hibernate fails to execute query + //can throw ClassCast exception, ConverterNotFoundException and more. throw toDataProblem(ex) } } @@ -319,7 +320,7 @@ class MangoDetachedCriteria extends DetachedCriteria { try { def list = hq.list(queryInfo.query, queryInfo.paramMap, args) return list as List - } catch (IllegalArgumentException | QueryException | ClassCastException ex) { + } catch (RuntimeException ex) { //Hibernate throws IllegalArgumentException when Antlr fails to parse query //and throws QueryException when hibernate fails to execute query //of cast exception, if type of value doesnt match field type diff --git a/gorm-tools/src/test/groovy/gorm/tools/mango/DefaultMangoQuerySpec.groovy b/gorm-tools/src/test/groovy/gorm/tools/mango/DefaultMangoQuerySpec.groovy index 8bcb2270e..d804497b8 100644 --- a/gorm-tools/src/test/groovy/gorm/tools/mango/DefaultMangoQuerySpec.groovy +++ b/gorm-tools/src/test/groovy/gorm/tools/mango/DefaultMangoQuerySpec.groovy @@ -5,6 +5,8 @@ package gorm.tools.mango import org.springframework.beans.factory.annotation.Autowired +import spock.lang.IgnoreRest +import spock.lang.Issue import spock.lang.Specification import testing.Address import testing.AddyNested @@ -192,6 +194,7 @@ class DefaultMangoQuerySpec extends Specification implements GormHibernateTest { ex.detail.contains("Text 'xxx' could not be parsed") } + @Issue("#3227") void "query fails with class cast exception"() { when: Cust.query("location":[[address:['add 1']]]).list() @@ -202,4 +205,16 @@ class DefaultMangoQuerySpec extends Specification implements GormHibernateTest { ex.detail.contains "java.util.ArrayList cannot be cast to class java.lang.String" } + + @Issue("#3189") + void "no converters found"() { + when: + Cust.query("location":"add 1").list() + + then: + DataProblemException ex = thrown() + ex.code == 'error.query.invalid' + ex.detail.contains "No converter found capable of converting from type [java.lang.String] to type [testing.Address]" + } + } From 68e899723ab7f8ee36fb332d066a63d96a546648 Mon Sep 17 00:00:00 2001 From: Sudhir Nimavat Date: Wed, 18 Jun 2025 12:10:20 +0530 Subject: [PATCH 3/3] fix --- .../tools/mango/MangoDetachedCriteria.groovy | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/gorm-tools/src/main/groovy/gorm/tools/mango/MangoDetachedCriteria.groovy b/gorm-tools/src/main/groovy/gorm/tools/mango/MangoDetachedCriteria.groovy index b190b11b1..58810e5a4 100644 --- a/gorm-tools/src/main/groovy/gorm/tools/mango/MangoDetachedCriteria.groovy +++ b/gorm-tools/src/main/groovy/gorm/tools/mango/MangoDetachedCriteria.groovy @@ -24,7 +24,7 @@ import org.grails.datastore.mapping.query.api.QueryArgumentsAware import org.grails.datastore.mapping.query.api.QueryableCriteria import org.grails.orm.hibernate.AbstractHibernateSession import org.hibernate.QueryException -import org.springframework.beans.factory.NoSuchBeanDefinitionException +import org.springframework.core.convert.ConverterNotFoundException import gorm.tools.beans.Pager import gorm.tools.mango.api.QueryArgs @@ -39,7 +39,6 @@ import yakworks.api.problem.ThrowableProblem import yakworks.api.problem.data.DataProblem import yakworks.commons.lang.NameUtils import yakworks.gorm.config.GormConfig -import yakworks.spring.AppCtx /** * This is here to make it easier to build criteria with domain bean paths @@ -264,10 +263,13 @@ class MangoDetachedCriteria extends DetachedCriteria { } return query.list() } - } catch (RuntimeException ex) { + } catch (IllegalArgumentException | QueryException | ClassCastException | ConverterNotFoundException ex) { //Hibernate throws IllegalArgumentException when Antlr fails to parse query - //throws QueryException when hibernate fails to execute query - //can throw ClassCast exception, ConverterNotFoundException and more. + //QueryException when hibernate fails to execute query + //ClassCast exception, when the value type doesnt match the field type + //ConverterNotFoundException when trying to convert string to an association type, etc + //We catch individual exceptions instead of a catch all RuntimeException, so that when some thing fails + //it will be logged and we can see, or else, it will come to notice only when api user's report why some queries arent working. throw toDataProblem(ex) } } @@ -320,10 +322,13 @@ class MangoDetachedCriteria extends DetachedCriteria { try { def list = hq.list(queryInfo.query, queryInfo.paramMap, args) return list as List - } catch (RuntimeException ex) { + } catch (IllegalArgumentException | QueryException | ClassCastException | ConverterNotFoundException ex) { //Hibernate throws IllegalArgumentException when Antlr fails to parse query - //and throws QueryException when hibernate fails to execute query - //of cast exception, if type of value doesnt match field type + //QueryException when hibernate fails to execute query + //ClassCast exception, when the value type doesnt match the field type + //ConverterNotFoundException when trying to convert string to an association type, etc + //We catch individual exceptions instead of a catch all RuntimeException, so that when some thing fails + //it will be logged and we can see, or else, it will come to notice only when api user's report why some queries arent working. throw toDataProblem(ex) } }