Skip to content

feat!: union the emit and fail options into one reportAs - #315

Merged
alexander-akait merged 2 commits into
mainfrom
feat/union-emit-and-fail-options
Sep 8, 2026
Merged

feat!: union the emit and fail options into one reportAs#315
alexander-akait merged 2 commits into
mainfrom
feat/union-emit-and-fail-options

Conversation

@alexander-akait

@alexander-akait alexander-akait commented Sep 7, 2026

Copy link
Copy Markdown
Member

Summary

emitError, emitWarning, failOnError and failOnWarning become one option taking "error", "warning" or false. It says what a check reports its results as — and reporting one as a webpack error is what fails the build, so there is nothing left for a second option to say.

type reportAs = "error" | "warning" | false;
Value Effect
unset (default) Each result at its own severity: errors fail the build, warnings do not.
"error" Everything fails the build, warnings included.
"warning" Nothing fails the build; errors are reported as warnings.
false Nothing is reported. An outputReport is still written.

The name answers the question the option asks. emit was inherited from emitError/emitWarning, where the answer was whether to report at all. This option answers what to report a result as — and a name that says "whether" invites reading "error" as "errors only", which is exactly how it kept being misread while the shape was settling.

Left unset the default is unchanged, so a check no longer reports into errors and warnings by anyone's instruction — it does so because that is what its results are, and one value overrides it. quiet keeps dropping the warnings before that, which is how a check's errors are reported alone.

The plugin no longer aborts the compilation. A result reported as a webpack error fails the build the way every other webpack error does, with the assets still written. Worth knowing, because it was the one thing failOn did that reportAs does not: webpack's own bail does not reach an error pushed at processAssets — measured, bail: true still returns stats with hasErrors() true rather than erroring the run — so that abort was the plugin's alone, and it goes with failOn.

Nothing else is lost. The four booleans expressed six distinct behaviours between them; all six are still reachable, measured on real builds — where a result of each severity landed, and whether the build came out failed:

Behaviour Said as An error lands in A warning lands in Build failed
report nothing reportAs: false ignored ignored no
errors only, not fatal reportAs: "warning", quiet: true warnings ignored no
both reported, not fatal reportAs: "warning" warnings warnings no
errors fatal, warnings hidden quiet: true errors ignored yes
errors fatal, warnings warn unset errors warnings yes
everything fatal reportAs: "error" errors errors yes

The schema refuses true, "info", [], ["error"] and { error: "error" }.

reportAs and quiet are now applied by the plugin rather than by each adapter, so splitResults is a pure split by the result's own severity and a check shipped outside this package — which cannot know about either option — gets both for free. Writing the docs is what surfaced that: the sample adapter in the README honoured neither.

What kind of change does this PR introduce?

feat (breaking).

Did you add tests for your changes?

Yes. The eight files named after single booleans — emit-error, emit-warning, fail-on-error, fail-on-warning, twice over for ESLint and Stylelint — become one report-as.test.js per check, covering every value, quiet alongside it, an option written out as undefined, and what the schema refuses; plus a case for a third-party adapter implementing neither option. 121 passing.

Does this PR introduce a breaking change?

Yes: emitError, emitWarning, failOnError and failOnWarning are gone, and the plugin no longer aborts the compilation. Nothing has shipped under this package name, so it lands in the same unreleased major as the rename. The README's migration guide carries the old-to-new table.

If relevant, what needs to be documented once your changes are merged or what have you already documented?

Documented here: the Errors and warnings section rewritten for the one option, both migration guides given the old-to-new table and the note that the build is no longer aborted, and the adapter contract in Adding a check corrected to say the plugin applies reportAs and quiet. The note about development mode not failing the build is dropped along with the behaviour. The changeset is a major. Nothing is left outstanding beyond whatever the eventual webpack.js.org page for the renamed plugin needs.

Use of AI

Written with Claude Code, driven interactively. It proposed a boolean, then a severity list, then a threshold, then an object keyed by severity; I turned down each one — a run reporting into errors and warnings at once is the wrong shape, and two options for one question is one too many — and then asked for a better name than emit. It verified rather than assumed where it mattered: that bail does not cover an error pushed at processAssets, so it could say what dropping the abort actually costs, and that all six behaviours survive, by measuring where each severity lands. It also found that a merged default let an explicit undefined silence the plugin, and that the sample adapter in the README ignored two options — which is what moved them into the plugin. I reviewed the result.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GzZci4NQeiqwdrVfd7dGXy

@alexander-akait
alexander-akait force-pushed the feat/union-emit-and-fail-options branch from 479af01 to ecbd791 Compare September 7, 2026 18:15
`emitError` and `emitWarning` become one `emit`, and `failOnError` and
`failOnWarning` one `failOn`. Each takes `"warning"`, `"error"` or `false`,
naming the least severe result it takes in, so `"warning"` covers the errors
above it and `false` covers nothing.

Reporting the errors of a check while hiding its warnings is a threshold, not
a set, so one value says it and no combination of two spells a state that is
not one. `emitError: false` alone loses its spelling with them: showing a
check's warnings while hiding its errors was never useful.

Defaults carry the old behaviour over: `emit` is `"warning"`, and `failOn` is
`"error"` outside `development` mode and `false` inside it. `quiet` is now
exactly `emit: "error"`. Both options resolve through `??`, so one written out
as `undefined` reads as the one left unwritten.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GzZci4NQeiqwdrVfd7dGXy
@alexander-akait
alexander-akait force-pushed the feat/union-emit-and-fail-options branch from ecbd791 to 2507357 Compare September 7, 2026 18:53
@alexander-akait alexander-akait changed the title feat!: union the emit and fail options feat!: union the emit and fail options into one Sep 7, 2026
@alexander-akait
alexander-akait force-pushed the feat/union-emit-and-fail-options branch 2 times, most recently from a663cc5 to 586aba6 Compare September 7, 2026 20:48
`emitError`, `emitWarning`, `failOnError` and `failOnWarning` become one
option taking `"error"`, `"warning"` or `false`. It says what a check reports
its results as, and reporting one as a webpack error is what fails the build,
so there is nothing left for a second option to say.

    reportAs: undefined  // each result at its own severity: errors fail, warnings do not
    reportAs: "error"    // everything fails the build, warnings included
    reportAs: "warning"  // nothing fails the build
    reportAs: false      // nothing is reported

The name answers the question the option asks. `emit` was inherited from
`emitError` and `emitWarning`, where the answer was whether to report at all;
this one answers what to report a result as, and a name that says "whether"
invites reading `"error"` as "errors only".

Left unset the default is unchanged, so a check no longer reports into errors
and warnings by anyone's instruction — it does so because that is what its
results are, and one value overrides it. `quiet` keeps dropping the warnings
before that, which is how the errors are reported alone.

The plugin no longer aborts the compilation. A result reported as a webpack
error fails the build the way every other webpack error does, with the assets
still written; webpack's own `bail` does not reach an error pushed this late,
so the abort was the plugin's alone and is gone with `failOn`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GzZci4NQeiqwdrVfd7dGXy
@alexander-akait
alexander-akait force-pushed the feat/union-emit-and-fail-options branch from 586aba6 to 4815bcf Compare September 8, 2026 09:14
@alexander-akait alexander-akait changed the title feat!: union the emit and fail options into one feat!: union the emit and fail options into one reportAs Sep 8, 2026
@alexander-akait
alexander-akait merged commit 9763cda into main Sep 8, 2026
13 checks passed
@alexander-akait
alexander-akait deleted the feat/union-emit-and-fail-options branch September 8, 2026 09:19
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.

1 participant