15
15
*/
16
16
package org .springframework .data .jpa .repository .query ;
17
17
18
+ import java .util .List ;
19
+
18
20
import org .antlr .v4 .runtime .BaseErrorListener ;
21
+ import org .antlr .v4 .runtime .CommonToken ;
22
+ import org .antlr .v4 .runtime .InputMismatchException ;
23
+ import org .antlr .v4 .runtime .NoViableAltException ;
19
24
import org .antlr .v4 .runtime .RecognitionException ;
20
25
import org .antlr .v4 .runtime .Recognizer ;
21
26
27
+ import org .springframework .util .ObjectUtils ;
28
+
22
29
/**
23
30
* A {@link BaseErrorListener} that will throw a {@link BadJpqlGrammarException} if the query is invalid.
24
31
*
@@ -43,7 +50,48 @@ class BadJpqlGrammarErrorListener extends BaseErrorListener {
43
50
@ Override
44
51
public void syntaxError (Recognizer <?, ?> recognizer , Object offendingSymbol , int line , int charPositionInLine ,
45
52
String msg , RecognitionException e ) {
46
- throw new BadJpqlGrammarException ("Line " + line + ":" + charPositionInLine + " " + msg , grammar , query , null );
53
+ throw new BadJpqlGrammarException (formatMessage (offendingSymbol , line , charPositionInLine , msg , e , query ), grammar ,
54
+ query , null );
55
+ }
56
+
57
+ /**
58
+ * Rewrite the error message.
59
+ */
60
+ private static String formatMessage (Object offendingSymbol , int line , int charPositionInLine , String message ,
61
+ RecognitionException e , String query ) {
62
+
63
+ String errorText = "At " + line + ":" + charPositionInLine ;
64
+
65
+ if (offendingSymbol instanceof CommonToken ct ) {
66
+
67
+ String token = ct .getText ();
68
+ if (!ObjectUtils .isEmpty (token )) {
69
+ errorText += " and token '" + token + "'" ;
70
+ }
71
+ }
72
+ errorText += ", " ;
73
+
74
+ if (e instanceof NoViableAltException ) {
75
+
76
+ errorText += message .substring (0 , message .indexOf ('\'' ));
77
+ if (query .isEmpty ()) {
78
+ errorText += "'*' (empty query string)" ;
79
+ } else {
80
+
81
+ List <String > list = query .lines ().toList ();
82
+ String lineText = list .get (line - 1 );
83
+ String text = lineText .substring (0 , charPositionInLine ) + "*" + lineText .substring (charPositionInLine );
84
+ errorText += "'" + text + "'" ;
85
+ }
86
+
87
+ } else if (e instanceof InputMismatchException ) {
88
+ errorText += message .substring (0 , message .length () - 1 ).replace (" expecting {" ,
89
+ ", expecting one of the following tokens: " );
90
+ } else {
91
+ errorText += message ;
92
+ }
93
+
94
+ return errorText ;
47
95
}
48
96
49
97
}
0 commit comments