Skip to content

API Design: JsonPath.compile() should declare or document InvalidPathException for better developer experience #1051

@leofernandesmo

Description

@leofernandesmo

While performing fuzz testing on the JsonPath library, I discovered that the JsonPath.compile(String jsonPath) method can throw InvalidPathException (which extends RuntimeException). Still, this behavior is not explicitly declared in the method signature or documented in the JavaDoc.

// Current method signature - no indication of possible exceptions
public static JsonPath compile(String jsonPath)

// But can throw:
com.jayway.jsonpath.InvalidPathException: Could not parse token starting at position 1. Expected ?, ', 0-9, *

Examples of Exception Cases Found
During fuzzing, several scenarios consistently trigger InvalidPathException:

  • Invalid syntax: Could not parse token starting at position 1. Expected ?, ', 0-9, *
  • Malformed paths: Path must not end with a '.' or '..'
  • Unclosed brackets: Property has not been closed - missing closing '
  • Invalid wildcard tokens: Expected wildcard token to end with ']' on position 3
  • Function syntax errors: Arguments to function: '@' are not closed properly

This design creates some issues.

What about enhancing documentation:

 /**
 * Compiles a JsonPath expression.
 * 
 * @param jsonPath the JsonPath expression to compile
 * @return compiled JsonPath object
 * @throws InvalidPathException if the path syntax is invalid (unchecked)
 * 
 * @example
 * <pre>
 * try {
 *     JsonPath path = JsonPath.compile("$.store.book[*].author");
 * } catch (InvalidPathException e) {
 *     // Handle invalid path syntax
 * }
 * </pre>
 */

Or create a Checked Exception Alternative (Major Version)

public static JsonPath compileChecked(String jsonPath) throws JsonPathParseException {
    // throws checked exception
}

Or even a functional approach.

public static Optional<JsonPath> tryCompile(String jsonPath) {
    try {
        return Optional.of(compile(jsonPath));
    } catch (InvalidPathException e) {
        return Optional.empty();
    }
}

I apologize in advance for any duplicates, and I'm available if you would prefer that I submit a PR with one of the solutions.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions