Skip to content

refactor(core): migrate issue handling to Arrow IorRaise#30

Open
halotukozak wants to merge 3 commits intomasterfrom
refactor/issue-model
Open

refactor(core): migrate issue handling to Arrow IorRaise#30
halotukozak wants to merge 3 commits intomasterfrom
refactor/issue-model

Conversation

@halotukozak
Copy link
Member

@halotukozak halotukozak commented Mar 25, 2026

Motivation

The previous issue/error model mixed concerns — SpecValidator.ValidationIssue carried both errors and warnings in a flat list, SpecParser used either with ParseResult.Failure as the error type (conflating parse-level errors with domain errors), and swagger parser messages were threaded through as raw strings. This made it hard to distinguish fatal errors from recoverable warnings and led to short-circuiting where accumulation was intended.

Changes

New domain types (Issue.kt)

  • Issue.Error — fatal parse/validation failure (single, not accumulated)
  • Issue.Warning — non-fatal observation (accumulated via IorRaise<Nel<Issue.Warning>>)
  • Warnings typealias for the IorRaise context

Arrow helpers (ArrowHelpers.kt)

  • ensureOrAccumulate / ensureNotNullOrAccumulate — context-receiver counterparts of Arrow's accumulate-scoped functions, usable directly in IorRaise context without nesting

SpecParser

  • parse() now uses iorNel { either { … } }Ior accumulates warnings while Either short-circuits on the first fatal error
  • Swagger parser messages are promoted to Issue.Warning and accumulated via Ior
  • ParseResult.Failure carries a single Issue.Error instead of List<String>
  • Internal Raise<ParseResult.Failure> contexts replaced with Raise<Issue.Error> + Warnings

SpecValidator

  • Removed ValidationIssue sealed hierarchy — all checks now emit Issue.Warning via Warnings context
  • Previous "errors" (e.g. missing info) downgraded to warnings (spec can still be partially processed)
  • Uses new ensureOrAccumulate / ensureNotNullOrAccumulate helpers

Gradle plugin (JustworksGenerateTask)

  • Warnings are logged before checking for failure (previously only logged on success path)

Tests

  • SpecValidatorTest — validates against List<Issue.Warning> via iorNel helper
  • SpecParserTest — SPEC-03 tests updated: missing info is now a warning, not a fatal error
  • IntegrationTest / SpecParserTestBase — adapted to Issue.Error on failure path

Test plan

  • All existing tests pass
  • SpecValidatorTest updated for IorRaise-based API
  • SpecParserTest SPEC-03 tests reflect warning-not-error semantics
  • Inline YAML spec tests pass (previously broken by accumulate/raise short-circuiting)

…arnings

Replace SpecValidator.ValidationIssue and string-based error lists with
typed Issue.Error/Issue.Warning and Arrow's IorRaise for non-short-circuiting
warning accumulation. ParseResult now carries List<Issue.Warning> and a
single Issue.Error on failure.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link

github-actions bot commented Mar 25, 2026

Coverage Report

Overall Project 94.99% -0.44% 🍏
Files changed 87.41% 🍏

File Coverage
ArrowHelpers.kt 100% 🍏
SpecParser.kt 93.77% -0.45% 🍏
Issue.kt 90% -10% 🍏
SpecValidator.kt 76.7% -23.3%

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors OpenAPI spec parsing/validation to use typed issues (Issue.Error / Issue.Warning) and Arrow’s IorRaise to accumulate warnings without short-circuiting, while returning a single typed error on failure.

Changes:

  • Introduces Issue and Warnings = IorRaise<Nel<Issue.Warning>> plus a warn() helper for warning accumulation.
  • Rewrites SpecParser.parse and SpecValidator.validate to use the new typed issue + warning accumulation approach.
  • Updates Gradle plugin and tests to consume ParseResult with warnings: List<Issue.Warning> and Failure(error: Issue.Error).

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
plugin/src/main/kotlin/com/avsystem/justworks/gradle/JustworksGenerateTask.kt Logs typed warnings and throws on typed parse failure.
core/src/main/kotlin/com/avsystem/justworks/core/Issue.kt Adds typed Issue model, Warnings alias, and warn() helper.
core/src/main/kotlin/com/avsystem/justworks/core/parser/SpecParser.kt Migrates parse pipeline to iorNel warning accumulation and typed error results.
core/src/main/kotlin/com/avsystem/justworks/core/parser/SpecValidator.kt Simplifies validation to if checks that accumulate warnings via warn().
core/src/test/kotlin/com/avsystem/justworks/core/parser/SpecValidatorTest.kt Updates validator tests to collect warnings via iorNel folding.
core/src/test/kotlin/com/avsystem/justworks/core/parser/SpecParserTestBase.kt Updates failure assertion messaging for typed errors.
core/src/test/kotlin/com/avsystem/justworks/core/parser/SpecParserTest.kt Updates SPEC-03 expectations to warnings and adapts error collection.
core/src/test/kotlin/com/avsystem/justworks/core/gen/IntegrationTest.kt Updates parse failure assertions to typed errors.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…e warn with ensureOrAccumulate / ensureNotNullOrAccumulate
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Change `ensureOrAccumulate` condition to check for empty links instead of non-empty.
@halotukozak halotukozak requested a review from MattK97 March 25, 2026 14:09
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