Skip to content

Add v4 catchRefailToTapError diagnostic - #744

Merged
mattiamanzati merged 1 commit into
mainfrom
feat/catch-refail-to-tap-error
Sep 14, 2026
Merged

mattiamanzati merged 1 commit into
mainfrom
feat/catch-refail-to-tap-error

Conversation

@mattiamanzati

Copy link
Copy Markdown
Contributor

Adds the v4-only catchRefailToTapError suggestion for Effect.catch handlers that run an effect and then unconditionally re-fail the original error.

For example, this handler now suggests Effect.tapError:

save.pipe(
  Effect.catch(error => rollback.pipe(Effect.andThen(Effect.fail(error))))
)

// Suggested form:
save.pipe(Effect.tapError(() => rollback))

The diagnostic reads: “Use Effect.tapError to observe the error and preserve the original failure without having to re-fail it.”

Detection uses normalized piping flows and lazy-expression parsing. It accepts terminal Effect.andThen with a direct fail or zero-argument callback, and terminal Effect.flatMap with a zero-argument callback. The fail must reference the same unassigned handler parameter. Fixtures cover call forms, aliases, conditional recovery, changed errors, shadowing, reassignment, and work after the fail.

This initial implementation excludes generator handlers, selective catches, and v3. It provides a diagnostic without an automatic fix. Includes generated docs, configuration schemas, metadata, and a minor changeset.

Validation: pnpm setup-repo, pnpm lint, pnpm check, and pnpm test.

Closes #653 with the initial scope narrowed to the patterns above.

@mattiamanzati
mattiamanzati merged commit ae1ed02 into main Sep 14, 2026
9 checks passed
@mattiamanzati
mattiamanzati deleted the feat/catch-refail-to-tap-error branch September 14, 2026 09:57
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.

Rule proposal: catch handler that re-fails the same error re-implements Effect.tapError

1 participant