Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 11, 2025

Overview

This PR adds 78 comprehensive unit tests that validate the Musoq query engine produces meaningful, helpful error messages when users provide invalid SQL queries or perform invalid schema operations. Additionally, it improves error handling across both Parser and Evaluator by replacing generic exceptions with domain-specific exceptions and enhancing error messages.

Problem

While the Musoq query engine has robust error handling, there were several key issues:

  1. No systematic test coverage validating that error messages are helpful and informative
  2. Parser was throwing generic NotSupportedException instead of SQL-specific SyntaxException with query context
  3. Evaluator was using generic .NET exceptions (InvalidOperationException, NotSupportedException) instead of domain-specific exceptions
  4. Missing input validation guards for edge cases

Without proper tests and meaningful exceptions, error message quality could degrade over time, and users would receive unhelpful generic .NET exceptions.

Solution

Part 1: Comprehensive Error Validation Tests (48 tests)

Added three new test files with comprehensive coverage of invalid query scenarios:

1. Parser-Level Syntax Tests (21 tests)

File: Musoq.Parser.Tests/InvalidQuerySyntaxTests.cs

Tests validate meaningful errors for SQL syntax violations:

  • Missing clauses (SELECT, FROM)
  • Invalid JOIN syntax (missing ON clause)
  • Unclosed parentheses and brackets
  • Invalid WHERE/GROUP BY/ORDER BY/HAVING syntax
  • Invalid CASE WHEN (missing THEN/END)
  • Trailing and multiple commas
  • Invalid UNION/EXCEPT/CTE syntax
  • Invalid IN and BETWEEN operators

Example validated error:

SyntaxException: "Expected token is FROM but received <token>"

2. Evaluator-Level Semantic/Runtime Tests (20 tests)

File: Musoq.Evaluator.Tests/InvalidQueryEvaluationTests.cs

Tests validate meaningful errors for semantic and runtime issues:

  • Non-existent columns/functions/schemas
  • Ambiguous column names in joins
  • Invalid property access on null objects
  • Type mismatches in operations
  • Invalid aggregate function usage
  • Set operation errors (column count mismatch)
  • Division by zero
  • Invalid joins and CTE references

Example validated errors:

UnknownColumnOrAliasException: "Column or Alias NonExistentColumn could not be found."
CannotResolveMethodException: "Method NonExistentFunction with argument types String cannot be resolved"
AmbiguousColumnException: "Column 'Name' is ambiguous. It exists in multiple tables."

3. Schema-Level Operation Tests (7 tests)

File: Musoq.Schema.Tests/InvalidSchemaOperationsTests.cs

Tests validate meaningful errors for schema-level operations:

  • Non-existent method resolution
  • Empty/whitespace schema names
  • Null parameter validation in method managers
  • Schema provider behavior

Example validated error:

SchemaArgumentException: "Schema name cannot be empty when initializing a schema"

Part 2: Parser Error Handling Improvements (20 tests)

Files:

  • Musoq.Parser.Tests/ImprovedErrorMessagesTests.cs (10 tests)
  • Musoq.Parser.Tests/InputValidationGuardsTests.cs (10 tests)

Changes Made:

  • Replaced all 11 instances of NotSupportedException with SyntaxException in Parser.cs
  • Enhanced error messages to be specific, actionable, and include helpful guidance
  • Added 10 tests validating that Parser throws SQL-specific exceptions with meaningful messages
  • Added 10 tests validating input validation guards for edge cases (empty SELECT, consecutive commas, missing conditions)

Examples of improved error messages:

Before:

throw new NotSupportedException("Cannot recognize if query is regular or reordered");

After:

throw new SyntaxException("Expected SELECT or FROM keyword to start query, but received {token}", queryContext);

Before:

throw new NotSupportedException("Group by clause does not have any fields");

After:

throw new SyntaxException("GROUP BY clause requires at least one column or expression. Please specify columns to group by.", queryContext);

Impact: Users now get SQL-specific errors with query context instead of generic .NET exceptions.

Part 3: Evaluator Exception Type Improvements

New Exception Created:

  • CodeGenerationException - Domain-specific exception for code generation failures with factory methods for common scenarios

Files Modified:

  • Musoq.Evaluator/Visitors/Helpers/AccessObjectArrayNodeProcessor.cs - Now throws CodeGenerationException
  • Musoq.Evaluator/Visitors/Helpers/ComparisonOperationVisitorHelper.cs - Now throws VisitorException.CreateForStackUnderflow()
  • Musoq.Evaluator/Visitors/Helpers/BinaryOperationVisitorHelper.cs - Now throws VisitorException.CreateForStackUnderflow()
  • Musoq.Evaluator/Visitors/Helpers/LogicalOperationVisitorHelper.cs - Now throws VisitorException.CreateForStackUnderflow()
  • Musoq.Evaluator/Visitors/Helpers/SyntaxBinaryOperationHelper.cs - Now throws VisitorException.CreateForStackUnderflow()

Example improvement:

Before:

if (nodes.Count < 2)
    throw new InvalidOperationException("Stack must contain at least 2 nodes for binary operation");

After:

if (nodes.Count < 2)
    throw VisitorException.CreateForStackUnderflow("ComparisonOperationVisitorHelper", "Binary Operation", 2, nodes.Count);

Improved error message:

Visitor 'ComparisonOperationVisitorHelper' failed during 'Binary Operation': 
Stack underflow detected. Expected at least 2 item(s) on the stack, but found 0. 
This typically indicates an AST processing error or malformed query structure. 
Please verify the query syntax and structure.

Part 4: Comprehensive Documentation

Files Created:

  • ERROR_HANDLING_ANALYSIS.md - Detailed analysis of all error handling issues found, prioritized roadmap for improvements
  • ERROR_HANDLING_IMPROVEMENTS.md - Complete implementation summary of all improvements made
  • INVALID_QUERY_TESTS.md - Comprehensive test coverage documentation with examples

Key findings documented:

  • No Error Recovery: Parser stops at first error (documented as high priority for future work)
  • Remaining Generic Exceptions: ~10 instances in Evaluator still to address (documented for future work)
  • Additional Input Validation: Opportunities for more guards (documented with specific recommendations)

Error Message Quality Standards

All tests verify that errors:

  1. Are thrown - No silent failures
  2. Have non-empty messages - Every error has content
  3. Are meaningful - Messages contain:
    • The specific element that caused the error (column name, function name, etc.)
    • Context about where the error occurred
    • Clear indication of what went wrong
    • Helpful guidance for resolution

Test Validation Approach

Each test follows a consistent pattern:

try
{
    CreateAndRunVirtualMachine(invalidQuery, sources);
    Assert.Fail("Expected an exception for invalid query");
}
catch (Exception exc)
{
    Assert.IsNotNull(exc.Message);
    Assert.IsTrue(exc.Message.Length > 0, "Error message should be meaningful");
    Assert.IsTrue(exc.Message.Contains("RelevantKeyword"),
        $"Error should mention the problematic element: {exc.Message}");
}

Test Results

All 2,240 repository tests passing (100%)

  • Parser: 201 tests (21 invalid query + 10 improved error handling + 10 input validation guards)
  • Evaluator: 1,498 tests (20 invalid query + updated exception type tests)
  • Schema: 118 tests (7 invalid operations)
  • Plugins: 421 tests
  • Converter: 2 tests

New tests added: 78 total

  • Invalid query tests: 48 (21 parser + 20 evaluator + 7 schema)
  • Parser improvement tests: 20 (10 improved errors + 10 input guards)
  • Updated existing tests: 15+ test files for new exception types

No regressions introduced.

Benefits

  1. Regression Protection - Ensures error messages remain helpful as code evolves
  2. Developer Experience - Users get clear, actionable, domain-specific error messages with context
  3. Documentation - Test names serve as documentation of invalid query scenarios
  4. Code Quality - Forces the engine to handle edge cases gracefully
  5. Improved Error Handling - Consistent use of domain-specific exceptions across Parser and Evaluator
  6. Stack Underflow Details - Errors now show expected vs actual stack size with helpful guidance
  7. Code Generation Errors - Clearly identify which component and operation failed
  8. Roadmap for Future Work - Comprehensive analysis documents guide next improvements

Exception Type Improvements Summary

  • Parser: 11 NotSupportedExceptionSyntaxException
  • Evaluator: 6 generic exceptions → domain-specific exceptions
    • 5 InvalidOperationExceptionVisitorException
    • 1 InvalidOperationExceptionCodeGenerationException

Running the Tests

# Run all new invalid query tests
dotnet test --filter "FullyQualifiedName~InvalidQuery OR FullyQualifiedName~InvalidSchemaOperations OR FullyQualifiedName~ImprovedErrorMessages OR FullyQualifiedName~InputValidationGuards"

# Run specific test suites
dotnet test Musoq.Parser.Tests --filter "FullyQualifiedName~InvalidQuerySyntaxTests"
dotnet test Musoq.Parser.Tests --filter "FullyQualifiedName~ImprovedErrorMessagesTests"
dotnet test Musoq.Parser.Tests --filter "FullyQualifiedName~InputValidationGuardsTests"
dotnet test Musoq.Evaluator.Tests --filter "FullyQualifiedName~InvalidQueryEvaluationTests"
dotnet test Musoq.Schema.Tests --filter "FullyQualifiedName~InvalidSchemaOperationsTests"

Future Work

See ERROR_HANDLING_ANALYSIS.md for detailed roadmap including:

  • Error recovery mechanism (high priority)
  • Additional input validation guards (medium priority)
  • Remaining Evaluator exception type improvements (medium priority)
  • Error message enhancements with suggestions and carets (low priority)
Original prompt

I want you to look at the repository, construct non valid queries of various kind and work on returning meaningfull errors, non valid queries should be enclosed within their own unit tests validating meaningfull errors is actually throwb


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Copilot AI changed the title [WIP] Add unit tests for non valid queries and error handling Add comprehensive unit tests for invalid SQL queries with meaningful error validation Oct 11, 2025
Copilot finished work on behalf of Puchaczov October 11, 2025 07:10
Copilot AI requested a review from Puchaczov October 11, 2025 07:10
@Puchaczov
Copy link
Owner

@copilot i want you to look at uncovered places and errors too, things that causes parsing or evaluator not meaningful errors, where there are missing guards or valuation, how good is parsing error recovery, can we make it better?

Copy link
Contributor Author

Copilot AI commented Oct 11, 2025

@copilot i want you to look at uncovered places and errors too, things that causes parsing or evaluator not meaningful errors, where there are missing guards or valuation, how good is parsing error re...

I've analyzed the Parser and Evaluator for error handling issues and made significant improvements:

✅ Completed (Commit fb1eaf6)

Parser Error Messages - All NotSupportedException Replaced

  • Fixed 11 instances where Parser threw NotSupportedException instead of SyntaxException

  • Improved error messages to be more specific and actionable:

    • "Expected SELECT or FROM keyword to start query" (was: "Cannot recognize if query is regular or reordered")
    • "GROUP BY clause requires at least one column or expression. Please specify columns to group by."
    • "Expected ASC or DESC in ORDER BY clause"
    • "Table or data source must have an alias. Use 'AS alias_name'..."
  • Added 10 new tests in ImprovedErrorMessagesTests.cs validating improved error handling

  • Result: Users now get SQL-specific errors with query context instead of generic .NET exceptions

📋 Analysis of Remaining Issues

Created ERROR_HANDLING_ANALYSIS.md with detailed findings:

1. No Error Recovery (High Priority)

  • Parser stops at first error - cannot report multiple errors
  • Users must fix errors one at a time
  • Recommendation: Implement panic-mode recovery at synchronization points (SELECT, FROM, WHERE, semicolons)

2. Evaluator Uses Generic Exceptions (Medium Priority)

  • 15+ InvalidOperationException instances
  • 10+ NotSupportedException instances
  • Should use domain-specific exceptions like CodeGenerationException, StackUnderflowException

3. Missing Input Validation Guards (Medium Priority)

  • ComposeFields() doesn't validate before processing
  • ComposeAlias() validates after instead of during
  • Token sequence validation gaps

4. Parser Could Be Better (Low Priority)

  • Add correction suggestions
  • Show error caret in query
  • Context-aware error messages

All 2,230 tests passing ✅ (10 new tests added)

Copilot AI changed the title Add comprehensive unit tests for invalid SQL queries with meaningful error validation Add comprehensive unit tests for invalid SQL queries and improve Parser error handling Oct 11, 2025
Copilot finished work on behalf of Puchaczov October 11, 2025 07:36
@Puchaczov
Copy link
Owner

@copilot document your findings and start working on fixes

Copy link
Contributor Author

Copilot AI commented Oct 11, 2025

@copilot document your findings and start working on fixes

Completed! Here's what was implemented:

✅ Findings Documented

Created comprehensive analysis in ERROR_HANDLING_ANALYSIS.md covering:

  • Parser error improvements (completed)
  • Missing error recovery (high priority for future)
  • Evaluator generic exceptions (partially addressed)
  • Input validation gaps (partially addressed)

✅ Fixes Implemented

1. Input Validation Guards (Commit 69463d1)

  • Added 10 new tests in InputValidationGuardsTests.cs
  • Validates edge cases: empty SELECT, consecutive commas, missing conditions
  • All 201 Parser tests passing

2. Improved Evaluator Exception Types (Commit 69463d1 + ff4acba)

Created CodeGenerationException:

  • Domain-specific exception for code generation errors
  • Replaces generic InvalidOperationException in code generation

Replaced generic exceptions with VisitorException:

  • Stack underflow errors now use VisitorException.CreateForStackUnderflow()
  • Provides helpful context: expected vs actual stack size
  • Updated 5 helper classes: AccessObjectArrayNodeProcessor, ComparisonOperationVisitorHelper, BinaryOperationVisitorHelper, LogicalOperationVisitorHelper, SyntaxBinaryOperationHelper

Updated all test expectations:

  • Fixed 15+ test files to expect correct exception types
  • Updated error message assertions

📊 Results

All 2,240 tests passing ✅ (10 new tests added)

See ERROR_HANDLING_ANALYSIS.md for remaining work (error recovery, additional guards).

Copilot AI changed the title Add comprehensive unit tests for invalid SQL queries and improve Parser error handling Add comprehensive unit tests for invalid SQL queries and improve error handling across Parser and Evaluator Oct 11, 2025
Copilot finished work on behalf of Puchaczov October 11, 2025 08:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants