Skip to content

Conversation

@Lil-Duckling-22
Copy link

@Lil-Duckling-22 Lil-Duckling-22 commented Nov 15, 2025

Replace TODO comment with detailed error formatting for validation failures. Error messages now include property names and constraint details instead of generic toString() output, making it easier to identify validation issues.

Summary by CodeRabbit

  • Bug Fixes

    • Validation error messages now show property-specific constraint details in a clear, structured format for easier debugging.
  • Tests

    • Added comprehensive unit tests covering invalid and valid manifest cases, nested-field checks, and the new error-message formatting.

✏️ Tip: You can customize this high-level summary in your review settings.

Replace TODO comment with detailed error formatting for validation failures.
Error messages now include property names and constraint details instead
of generic toString() output, making it easier to identify validation issues.
@coderabbitai
Copy link

coderabbitai bot commented Nov 15, 2025

Walkthrough

Validation error handling in the project loader was changed to produce structured, per-property constraint messages by importing ValidationError and formatting validation errors instead of using generic toString() output. A comprehensive unit test suite was added to assert the new error message layout and positive validation behavior.

Changes

Cohort / File(s) Summary
Validation error formatting
packages/common/src/project/load.ts
Added ValidationError import from class-validator; replaced generic error stringification with structured formatting that lists each property and its constraint messages before throwing the error.
Tests for manifest validation
packages/common/src/project/load.spec.ts
Added tests covering missing/invalid fields, nested property validation, error message layout (starts with "project validation failed." and lists per-property constraints), and a positive-case ensuring a valid manifest does not throw.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Verify correctness of the structured formatting logic for nested ValidationError instances and constraint message aggregation.
  • Ensure error message string matches tests' expectations (prefix, indentation, per-property lines).
  • Confirm no changes to public API surface or thrown error types beyond message formatting.
  • Review the new tests for completeness and flakiness (edge cases like empty strings, arrays, nested objects).

Poem

I nibble at schema, hop through each field,
I gather the errors and politely reveal—
"project validation failed," I softly declare,
One property per line, with meticulous care. 🐇🎋

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: improving validation error details in the validateCommonProjectManifest function, which is the core modification across both the implementation and test files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b26630d and ff31007.

📒 Files selected for processing (1)
  • packages/common/src/project/load.spec.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Use TypeScript throughout with strict configuration in the monorepo
Use Ethers.js for Ethereum integration

Files:

  • packages/common/src/project/load.spec.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use custom Jest configuration with module name mapping for workspace packages, enforce UTC timezone for tests, and handle Polkadot packages in transform ignore patterns

Files:

  • packages/common/src/project/load.spec.ts
packages/**/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Run ESLint with TypeScript support, Prettier, and various plugins across all TypeScript files using configured husky pre-commit hooks and lint-staged

Files:

  • packages/common/src/project/load.spec.ts
🧠 Learnings (1)
📚 Learning: 2025-11-25T02:34:46.620Z
Learnt from: CR
Repo: subquery/subql PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T02:34:46.620Z
Learning: Use TypeScript compilation with project references and generate OCLIF manifest for command discovery

Applied to files:

  • packages/common/src/project/load.spec.ts
🧬 Code graph analysis (1)
packages/common/src/project/load.spec.ts (1)
packages/common/src/project/load.ts (1)
  • validateCommonProjectManifest (90-101)
🔇 Additional comments (7)
packages/common/src/project/load.spec.ts (7)

1-4: LGTM! Clean imports and proper copyright header.

The import statement is minimal and correct, importing only the function under test.


6-23: Excellent documentation of the format improvement.

The before/after example directly addresses the maintainer's request to show how the error output has changed. This makes the improvement clear and provides valuable context for future maintainers.


24-56: Well-structured test validating the new error format.

The test comprehensively verifies the structured error message format through multiple assertions, checking both the overall structure and individual line formats. This directly validates the PR's core improvement.


58-88: Good coverage of property-specific constraint validation.

This test verifies that the structured format correctly identifies and reports constraints for a specific invalid property.


90-161: Comprehensive nested property validation tests.

These tests effectively verify that the structured error format works for nested properties (runner.query.name) and missing nested properties (network.chainId). The defensive conditionals are appropriate for format verification tests.


199-216: Essential positive test case.

Good practice to include a test verifying that valid manifests pass validation without errors. This ensures the validation improvements don't introduce false positives.


176-178: Remove fail() call or configure Jest to support it.

The fail() function is not available in modern Jest (v27+) by default, as it was removed when jest-circus replaced the Jasmine test runner. Either ensure the project is configured with jest-jasmine2 as the test runner, or remove the fail() call on line 178 and let the test fail naturally through the missing catch assertions. Alternatively, use expect.assertions() to verify the exception was caught.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/common/src/project/load.ts (1)

94-98: Excellent improvement to error messaging.

The structured error formatting is much more actionable than generic toString() output. The defensive check for constraints and clear property-level formatting will help developers quickly identify validation issues.

One optional enhancement: ValidationError objects can have nested errors via the children property for complex object validations. If manifest structures become more deeply nested in the future, consider recursively handling these children.

Example recursive approach if nested validation becomes relevant:

const formatError = (error: ValidationError, indent = '  '): string => {
  const property = error.property;
  const constraints = error.constraints ? Object.values(error.constraints).join(', ') : '';
  let message = `${indent}- ${property}${constraints ? ': ' + constraints : ''}`;
  
  if (error.children?.length) {
    const childMessages = error.children.map(child => formatError(child, indent + '  ')).join('\n');
    message += '\n' + childMessages;
  }
  
  return message;
};

const errorMsgs = errors.map(error => formatError(error)).join('\n');
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 45e1b6b and b26630d.

📒 Files selected for processing (1)
  • packages/common/src/project/load.ts (2 hunks)
🔇 Additional comments (1)
packages/common/src/project/load.ts (1)

8-8: Good addition for type safety.

Adding the ValidationError type import enables proper type annotation in the error formatting logic, improving code maintainability and IDE support.

@stwiname
Copy link
Collaborator

Hi @Lil-Duckling-22, thanks for your PR. Can you please update tests and provide an example of how the error output has changed

@Lil-Duckling-22
Copy link
Author

@stwiname sure thing, here are the tests

@stwiname
Copy link
Collaborator

stwiname commented Dec 7, 2025

How do the errors look for an error in a child object? e.g. An invalid filter on a mapping handler

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