Add error message for quoting errors

This commit is contained in:
Mubelotix
2025-08-13 17:14:36 +02:00
parent 8529e2161a
commit cdeca59587
4 changed files with 24 additions and 7 deletions

View File

@ -19,6 +19,7 @@ use Condition::*;
use crate::error::IResultExt; use crate::error::IResultExt;
use crate::value::parse_vector_value; use crate::value::parse_vector_value;
use crate::value::parse_vector_value_cut;
use crate::Error; use crate::Error;
use crate::ErrorKind; use crate::ErrorKind;
use crate::VectorFilter; use crate::VectorFilter;
@ -141,13 +142,13 @@ fn parse_vectors(input: Span) -> IResult<(Token, Option<Token>, VectorFilter<'_>
} }
let (input, embedder_name) = let (input, embedder_name) =
parse_vector_value(input).map_cut(ErrorKind::VectorFilterInvalidEmbedder)?; parse_vector_value_cut(input, ErrorKind::VectorFilterInvalidEmbedder)?;
let (input, filter) = alt(( let (input, filter) = alt((
map( map(
preceded(tag(".fragments"), |input| { preceded(tag(".fragments"), |input| {
let (input, _) = tag(".")(input).map_cut(ErrorKind::VectorFilterMissingFragment)?; let (input, _) = tag(".")(input).map_cut(ErrorKind::VectorFilterMissingFragment)?;
parse_vector_value(input).map_cut(ErrorKind::VectorFilterInvalidFragment) parse_vector_value_cut(input, ErrorKind::VectorFilterInvalidFragment)
}), }),
VectorFilter::Fragment, VectorFilter::Fragment,
), ),

View File

@ -79,6 +79,7 @@ pub enum ErrorKind<'a> {
MisusedGeoRadius, MisusedGeoRadius,
MisusedGeoBoundingBox, MisusedGeoBoundingBox,
VectorFilterLeftover, VectorFilterLeftover,
VectorFilterInvalidQuotes,
VectorFilterMissingEmbedder, VectorFilterMissingEmbedder,
VectorFilterInvalidEmbedder, VectorFilterInvalidEmbedder,
VectorFilterMissingFragment, VectorFilterMissingFragment,
@ -232,7 +233,7 @@ impl Display for Error<'_> {
writeln!(f, "Vector filter can only accept one of `fragments`, `userProvided`, `documentTemplate` or `regenerate`, but found both `{previous_filter_kind}` and `{value}`.")? writeln!(f, "Vector filter can only accept one of `fragments`, `userProvided`, `documentTemplate` or `regenerate`, but found both `{previous_filter_kind}` and `{value}`.")?
}, },
ErrorKind::VectorFilterInvalidFragment => { ErrorKind::VectorFilterInvalidFragment => {
writeln!(f, "The vector filter's fragment is invalid.")? writeln!(f, "The vector filter's fragment name is invalid.")?
} }
ErrorKind::VectorFilterMissingFragment => { ErrorKind::VectorFilterMissingFragment => {
writeln!(f, "The vector filter is missing a fragment name.")? writeln!(f, "The vector filter is missing a fragment name.")?
@ -246,6 +247,9 @@ impl Display for Error<'_> {
ErrorKind::VectorFilterOperation => { ErrorKind::VectorFilterOperation => {
writeln!(f, "Was expecting an operation like `EXISTS` or `NOT EXISTS` after the vector filter.")? writeln!(f, "Was expecting an operation like `EXISTS` or `NOT EXISTS` after the vector filter.")?
} }
ErrorKind::VectorFilterInvalidQuotes => {
writeln!(f, "The quotes in one of the values are inconsistent.")?
}
ErrorKind::ReservedKeyword(word) => { ErrorKind::ReservedKeyword(word) => {
writeln!(f, "`{word}` is a reserved keyword and thus cannot be used as a field name unless it is put inside quotes. Use \"{word}\" or \'{word}\' instead.")? writeln!(f, "`{word}` is a reserved keyword and thus cannot be used as a field name unless it is put inside quotes. Use \"{word}\" or \'{word}\' instead.")?
} }

View File

@ -1018,8 +1018,8 @@ pub mod tests {
22:23 _vectors.embedderName. EXISTS 22:23 _vectors.embedderName. EXISTS
"); ");
insta::assert_snapshot!(p(r#"_vectors."embedderName EXISTS"#), @r#" insta::assert_snapshot!(p(r#"_vectors."embedderName EXISTS"#), @r#"
The vector filter's embedder name is invalid. The quotes in one of the values are inconsistent.
30:30 _vectors."embedderName EXISTS 10:30 _vectors."embedderName EXISTS
"#); "#);
insta::assert_snapshot!(p(r#"_vectors."embedderNam"e EXISTS"#), @r#" insta::assert_snapshot!(p(r#"_vectors."embedderNam"e EXISTS"#), @r#"
The vector filter has leftover tokens. The vector filter has leftover tokens.
@ -1034,7 +1034,7 @@ pub mod tests {
32:39 _vectors.embedderName.fragments EXISTS 32:39 _vectors.embedderName.fragments EXISTS
"); ");
insta::assert_snapshot!(p(r#"_vectors.embedderName.fragments. EXISTS"#), @r" insta::assert_snapshot!(p(r#"_vectors.embedderName.fragments. EXISTS"#), @r"
The vector filter's fragment is invalid. The vector filter's fragment name is invalid.
33:40 _vectors.embedderName.fragments. EXISTS 33:40 _vectors.embedderName.fragments. EXISTS
"); ");
insta::assert_snapshot!(p(r#"_vectors.embedderName.fragments.test test EXISTS"#), @r" insta::assert_snapshot!(p(r#"_vectors.embedderName.fragments.test test EXISTS"#), @r"
@ -1042,7 +1042,7 @@ pub mod tests {
38:49 _vectors.embedderName.fragments.test test EXISTS 38:49 _vectors.embedderName.fragments.test test EXISTS
"); ");
insta::assert_snapshot!(p(r#"_vectors.embedderName.fragments. test EXISTS"#), @r" insta::assert_snapshot!(p(r#"_vectors.embedderName.fragments. test EXISTS"#), @r"
The vector filter's fragment is invalid. The vector filter's fragment name is invalid.
33:45 _vectors.embedderName.fragments. test EXISTS 33:45 _vectors.embedderName.fragments. test EXISTS
"); ");
insta::assert_snapshot!(p(r#"_vectors.embedderName .fragments. test EXISTS"#), @r" insta::assert_snapshot!(p(r#"_vectors.embedderName .fragments. test EXISTS"#), @r"

View File

@ -113,6 +113,18 @@ pub fn parse_vector_value(input: Span) -> IResult<Token> {
} }
} }
pub fn parse_vector_value_cut<'a>(input: Span<'a>, kind: ErrorKind<'a>) -> IResult<'a, Token<'a>> {
parse_vector_value(input).map_err(|e| match e {
nom::Err::Failure(e) => match e.kind() {
ErrorKind::Char(c) if *c == '"' || *c == '\'' => {
crate::Error::failure_from_kind(input, ErrorKind::VectorFilterInvalidQuotes)
}
_ => crate::Error::failure_from_kind(input, kind),
},
_ => crate::Error::failure_from_kind(input, kind),
})
}
/// value = WS* ( word | singleQuoted | doubleQuoted) WS+ /// value = WS* ( word | singleQuoted | doubleQuoted) WS+
pub fn parse_value(input: Span) -> IResult<Token> { pub fn parse_value(input: Span) -> IResult<Token> {
// to get better diagnostic message we are going to strip the left whitespaces from the input right now // to get better diagnostic message we are going to strip the left whitespaces from the input right now