Răsfoiți Sursa

Painless: improve bad regex pattern syntax error (#68520)

Adds extra information about the actual error in the pattern to the
error painless returns when you specify a bad pattern. This information
was hiding in the exception that `Pattern.compile` throws but isn't
included in its message so we were never showing it to anyone. These
error message include such gems as:

* named capturing group <name> does not exist
* Look-behind group does not have an obvious maximum length
* Unclosed counted closure

Now you'll get to know what you need to change about your pattern and
not just where it went wrong!
Nik Everett 4 ani în urmă
părinte
comite
fdb147ad6a

+ 1 - 1
modules/lang-painless/src/main/java/org/elasticsearch/painless/phase/DefaultSemanticAnalysisPhase.java

@@ -2092,7 +2092,7 @@ public class DefaultSemanticAnalysisPhase extends UserTreeBaseVisitor<SemanticSc
         } catch (PatternSyntaxException pse) {
             throw new Location(location.getSourceName(), location.getOffset() + 1 + pse.getIndex()).createError(
                     new IllegalArgumentException("invalid regular expression: " +
-                            "could not compile regex constant [" + pattern + "] with flags [" + flags + "]", pse));
+                            "could not compile regex constant [" + pattern + "] with flags [" + flags + "]: " + pse.getDescription(), pse));
         }
 
         semanticScope.putDecoration(userRegexNode, new ValueType(Pattern.class));

+ 18 - 1
modules/lang-painless/src/test/java/org/elasticsearch/painless/RegexTests.java

@@ -267,12 +267,29 @@ public class RegexTests extends ScriptTestCase {
         ScriptException e = expectThrows(ScriptException.class, () -> {
             exec("/\\ujjjj/"); // Invalid unicode
         });
-        assertEquals("invalid regular expression: could not compile regex constant [\\ujjjj] with flags []", e.getCause().getMessage());
+        assertEquals(
+            "invalid regular expression: could not compile regex constant [\\ujjjj] with flags []: Illegal Unicode escape sequence",
+            e.getCause().getMessage()
+        );
 
         // And make sure the location of the error points to the offset inside the pattern
         assertScriptStack(e,
                 "/\\ujjjj/",
                 "   ^---- HERE");
+
+        e = expectThrows(ScriptException.class, () -> {
+            exec("/(?< >.+)/"); // Invalid capture name
+        });
+        assertEquals(
+            "invalid regular expression: could not compile regex constant [(?< >.+)] with flags []: "
+                + "capturing group name does not start with a Latin letter",
+            e.getCause().getMessage()
+        );
+
+        // And make sure the location of the error points to the offset inside the pattern
+        assertScriptStack(e,
+                "/(?< >.+)/",
+                "    ^---- HERE");
     }
 
     public void testRegexAgainstNumber() {