Add new error

This commit is contained in:
Mubelotix
2025-08-13 09:58:16 +02:00
parent 2121819c66
commit b5ba0e42b3
4 changed files with 26 additions and 21 deletions

View File

@@ -135,6 +135,13 @@ fn parse_vectors(input: Span) -> IResult<(Token, Option<Token>, VectorFilter<'_>
// From this point, we are certain this is a vector filter, so our errors must be final. // From this point, we are certain this is a vector filter, so our errors must be final.
// We could use nom's `cut` but it's better to be explicit about the errors // We could use nom's `cut` but it's better to be explicit about the errors
if let Ok((_, space)) = tag::<_, _, ()>(" ")(input) {
return Err(crate::Error::new_failure_from_kind(
space,
ErrorKind::VectorFilterMissingEmbedder,
));
}
let (input, embedder_name) = let (input, embedder_name) =
parse_vector_value(input).map_cut(ErrorKind::VectorFilterInvalidEmbedder)?; parse_vector_value(input).map_cut(ErrorKind::VectorFilterInvalidEmbedder)?;

View File

@@ -54,7 +54,7 @@ impl<'a, T> IResultExt<'a> for IResult<'a, T> {
nom::Err::Error(e) => *e.context(), nom::Err::Error(e) => *e.context(),
nom::Err::Failure(e) => *e.context(), nom::Err::Failure(e) => *e.context(),
}; };
nom::Err::Failure(Error::new_from_kind(input, kind)) Error::new_failure_from_kind(input, kind)
}) })
} }
} }
@@ -79,6 +79,7 @@ pub enum ErrorKind<'a> {
MisusedGeoRadius, MisusedGeoRadius,
MisusedGeoBoundingBox, MisusedGeoBoundingBox,
VectorFilterLeftover, VectorFilterLeftover,
VectorFilterMissingEmbedder,
VectorFilterInvalidEmbedder, VectorFilterInvalidEmbedder,
VectorFilterMissingFragment, VectorFilterMissingFragment,
VectorFilterInvalidFragment, VectorFilterInvalidFragment,
@@ -112,6 +113,10 @@ impl<'a> Error<'a> {
Self { context, kind } Self { context, kind }
} }
pub fn new_failure_from_kind(context: Span<'a>, kind: ErrorKind<'a>) -> nom::Err<Self> {
nom::Err::Failure(Self::new_from_kind(context, kind))
}
pub fn new_from_external(context: Span<'a>, error: impl std::error::Error) -> Self { pub fn new_from_external(context: Span<'a>, error: impl std::error::Error) -> Self {
Self::new_from_kind(context, ErrorKind::External(error.to_string())) Self::new_from_kind(context, ErrorKind::External(error.to_string()))
} }
@@ -199,6 +204,9 @@ impl Display for Error<'_> {
ErrorKind::VectorFilterMissingFragment => { ErrorKind::VectorFilterMissingFragment => {
writeln!(f, "The vector filter is missing a fragment name.")? writeln!(f, "The vector filter is missing a fragment name.")?
} }
ErrorKind::VectorFilterMissingEmbedder => {
writeln!(f, "Was expecting embedder name but found nothing.")?
}
ErrorKind::VectorFilterInvalidEmbedder => { ErrorKind::VectorFilterInvalidEmbedder => {
writeln!(f, "The vector filter's embedder is invalid.")? writeln!(f, "The vector filter's embedder is invalid.")?
} }

View File

@@ -437,7 +437,7 @@ fn parse_geo_bounding_box(input: Span) -> IResult<FilterCondition> {
let (input, args) = parsed?; let (input, args) = parsed?;
if args.len() != 2 || args[0].len() != 2 || args[1].len() != 2 { if args.len() != 2 || args[0].len() != 2 || args[1].len() != 2 {
return Err(nom::Err::Failure(Error::new_from_kind(input, ErrorKind::GeoBoundingBox))); return Err(Error::new_failure_from_kind(input, ErrorKind::GeoBoundingBox));
} }
let res = FilterCondition::GeoBoundingBox { let res = FilterCondition::GeoBoundingBox {
@@ -458,7 +458,7 @@ fn parse_geo_point(input: Span) -> IResult<FilterCondition> {
))(input) ))(input)
.map_err(|e| e.map(|_| Error::new_from_kind(input, ErrorKind::ReservedGeo("_geoPoint"))))?; .map_err(|e| e.map(|_| Error::new_from_kind(input, ErrorKind::ReservedGeo("_geoPoint"))))?;
// if we succeeded we still return a `Failure` because geoPoints are not allowed // if we succeeded we still return a `Failure` because geoPoints are not allowed
Err(nom::Err::Failure(Error::new_from_kind(input, ErrorKind::ReservedGeo("_geoPoint")))) Err(Error::new_failure_from_kind(input, ErrorKind::ReservedGeo("_geoPoint")))
} }
/// geoPoint = WS* "_geoDistance(float WS* "," WS* float WS* "," WS* float) /// geoPoint = WS* "_geoDistance(float WS* "," WS* float WS* "," WS* float)
@@ -472,7 +472,7 @@ fn parse_geo_distance(input: Span) -> IResult<FilterCondition> {
))(input) ))(input)
.map_err(|e| e.map(|_| Error::new_from_kind(input, ErrorKind::ReservedGeo("_geoDistance"))))?; .map_err(|e| e.map(|_| Error::new_from_kind(input, ErrorKind::ReservedGeo("_geoDistance"))))?;
// if we succeeded we still return a `Failure` because `geoDistance` filters are not allowed // if we succeeded we still return a `Failure` because `geoDistance` filters are not allowed
Err(nom::Err::Failure(Error::new_from_kind(input, ErrorKind::ReservedGeo("_geoDistance")))) Err(Error::new_failure_from_kind(input, ErrorKind::ReservedGeo("_geoDistance")))
} }
/// geo = WS* "_geo(float WS* "," WS* float WS* "," WS* float) /// geo = WS* "_geo(float WS* "," WS* float WS* "," WS* float)
@@ -486,7 +486,7 @@ fn parse_geo(input: Span) -> IResult<FilterCondition> {
))(input) ))(input)
.map_err(|e| e.map(|_| Error::new_from_kind(input, ErrorKind::ReservedGeo("_geo"))))?; .map_err(|e| e.map(|_| Error::new_from_kind(input, ErrorKind::ReservedGeo("_geo"))))?;
// if we succeeded we still return a `Failure` because `_geo` filter is not allowed // if we succeeded we still return a `Failure` because `_geo` filter is not allowed
Err(nom::Err::Failure(Error::new_from_kind(input, ErrorKind::ReservedGeo("_geo")))) Err(Error::new_failure_from_kind(input, ErrorKind::ReservedGeo("_geo")))
} }
fn parse_error_reserved_keyword(input: Span) -> IResult<FilterCondition> { fn parse_error_reserved_keyword(input: Span) -> IResult<FilterCondition> {
@@ -1006,8 +1006,8 @@ pub mod tests {
1:25 _vectors _vectors EXISTS 1:25 _vectors _vectors EXISTS
"); ");
insta::assert_snapshot!(p(r#"_vectors. embedderName EXISTS"#), @r" insta::assert_snapshot!(p(r#"_vectors. embedderName EXISTS"#), @r"
The vector filter's embedder is invalid. Was expecting embedder name but found nothing.
10:30 _vectors. embedderName EXISTS 10:11 _vectors. embedderName EXISTS
"); ");
insta::assert_snapshot!(p(r#"_vectors .embedderName EXISTS"#), @r" insta::assert_snapshot!(p(r#"_vectors .embedderName EXISTS"#), @r"
Was expecting an operation `=`, `!=`, `>=`, `>`, `<=`, `<`, `IN`, `NOT IN`, `TO`, `EXISTS`, `NOT EXISTS`, `IS NULL`, `IS NOT NULL`, `IS EMPTY`, `IS NOT EMPTY`, `CONTAINS`, `NOT CONTAINS`, `STARTS WITH`, `NOT STARTS WITH`, `_geoRadius`, or `_geoBoundingBox` at `_vectors .embedderName EXISTS`. Was expecting an operation `=`, `!=`, `>=`, `>`, `<=`, `<`, `IN`, `NOT IN`, `TO`, `EXISTS`, `NOT EXISTS`, `IS NULL`, `IS NOT NULL`, `IS EMPTY`, `IS NOT EMPTY`, `CONTAINS`, `NOT CONTAINS`, `STARTS WITH`, `NOT STARTS WITH`, `_geoRadius`, or `_geoBoundingBox` at `_vectors .embedderName EXISTS`.

View File

@@ -132,31 +132,21 @@ pub fn parse_value(input: Span) -> IResult<Token> {
} }
match parse_geo_radius(input) { match parse_geo_radius(input) {
Ok(_) => { Ok(_) => return Err(Error::new_failure_from_kind(input, ErrorKind::MisusedGeoRadius)),
return Err(nom::Err::Failure(Error::new_from_kind(input, ErrorKind::MisusedGeoRadius)))
}
// if we encountered a failure it means the user badly wrote a _geoRadius filter. // if we encountered a failure it means the user badly wrote a _geoRadius filter.
// But instead of showing them how to fix his syntax we are going to tell them they should not use this filter as a value. // But instead of showing them how to fix his syntax we are going to tell them they should not use this filter as a value.
Err(e) if e.is_failure() => { Err(e) if e.is_failure() => {
return Err(nom::Err::Failure(Error::new_from_kind(input, ErrorKind::MisusedGeoRadius))) return Err(Error::new_failure_from_kind(input, ErrorKind::MisusedGeoRadius))
} }
_ => (), _ => (),
} }
match parse_geo_bounding_box(input) { match parse_geo_bounding_box(input) {
Ok(_) => { Ok(_) => return Err(Error::new_failure_from_kind(input, ErrorKind::MisusedGeoBoundingBox)),
return Err(nom::Err::Failure(Error::new_from_kind(
input,
ErrorKind::MisusedGeoBoundingBox,
)))
}
// if we encountered a failure it means the user badly wrote a _geoBoundingBox filter. // if we encountered a failure it means the user badly wrote a _geoBoundingBox filter.
// But instead of showing them how to fix his syntax we are going to tell them they should not use this filter as a value. // But instead of showing them how to fix his syntax we are going to tell them they should not use this filter as a value.
Err(e) if e.is_failure() => { Err(e) if e.is_failure() => {
return Err(nom::Err::Failure(Error::new_from_kind( return Err(Error::new_failure_from_kind(input, ErrorKind::MisusedGeoBoundingBox))
input,
ErrorKind::MisusedGeoBoundingBox,
)))
} }
_ => (), _ => (),
} }