Clean up console noise and enforce no-console in CI#2917
Conversation
tamararivera
left a comment
There was a problem hiding this comment.
Great change! the output looks so much better now
| @@ -144,22 +145,19 @@ function constructEdges(nodes: Node<NodeData>[]): DefaultEdge[] { | |||
| return m.receiving_endpoint !== undefined && m.sending_endpoint !== undefined && m.message_id === relatedTo && m.message_intent !== MessageIntent.Publish; | |||
| }); | |||
There was a problem hiding this comment.
Not related to this PR, but something that should be fixed: if the lint command throws an error we don't fail the script as we should, now it is failing silently: https://github.com/Particular/ServicePulse/actions/runs/23470361269/job/68291497710?pr=2917#step:5:24
There was a problem hiding this comment.
That is a bug that needs to be fixed.
I think it has to do with Powershell build.ps1
There was a problem hiding this comment.
The build should definitely fail, same as our C# builds fail with invalid code styles
| const loader = scenarios[scenarioName]; | ||
|
|
||
| if (!loader) { | ||
| // eslint-disable-next-line no-console |
There was a problem hiding this comment.
Suggestion: If you delete this line, you could test that console is not allowed in the CI pipeline.
|
This looks good @cquirosj, and it is a good idea to clean up all those leftovers. |
Given the majority of developers' background at Particular is C#, I honestly don't believe replacing "console" with "logger" is going to be very challenging 😉 |
## What changed **Removed leftover debug calls** `console.debug` calls used to trace auth flow steps, token lifecycle events, and auto-refresh state were removed. These were never intended to reach production and added no value outside of local debugging sessions. **Introduced a thin logger abstraction** A minimal `logger` module was added as the single place in the codebase allowed to call `console` directly. Legitimate error reporting in `catch` blocks and error handlers — places where surfacing failures is intentional — was migrated to `logger.error` / `logger.warn`. This keeps those signals visible in both dev and production builds while satisfying the linting rule everywhere else. **Added a CI-aware `no-console` lint rule** The ESLint config now enforces `no-console` as an **error** when `CI=true` (set automatically by GitHub Actions) and as a **warning** locally. This means developers can still freely use `console.x` during development without any friction, but leftover calls will fail the CI build before they can merge. **Added a lint step to the CI pipeline** A `Lint Frontend` step now runs `npm run lint` before the build, so the `no-console` rule is enforced on every PR and push to `master`.
deeae45 to
c872876
Compare
Good suggestion and worth considering for the future. Extending the logger with all methods and stripping debug/log/info in production builds is a cleaner, long-term architectural approach. The reason we didn't go that route here is that this PR is specifically motivated by noise in the CI test output, not just the production browser console. Tests run under Vitest where import.meta.env.PROD is false, so logger.debug() would still output during CI test runs. We'd also need import.meta.env.VITEST in the logger to suppress it, which means a production module becomes aware of the test environment. There's also a test isolation concern: with no-console always on, test files would be forced to import src/logger.ts (a module from the system under test) just to produce output, coupling test infrastructure to the SUT. The current approach sidesteps both: lint runs before tests execute, so any leftover console.x fails the build before it ever produces noise in the test step. Happy to revisit the fuller logger approach when we have a need for structured logging or remote error routing. |
This reverts commit 658d6e3.
TODO:
The problem
Over time,
console.debugandconsole.logcalls left behind from debugging sessions accumulated in the codebase. These had two undesirable effects:The challenge was fixing this without breaking the developer workflow. Developers rely on
console.debug,console.log,console.infoheavily during local development, and blocking that entirely would create friction with no benefit.What changed
Removed leftover debug calls
console.debugcalls used to trace auth flow steps, token lifecycle events, and auto-refresh state were removed. These were never intended to reach production and added no value outside of local debugging sessions. The same cleanup was applied to leftover calls in the test driver and test preconditions.Introduced a thin logger abstraction
A minimal
loggermodule was added as the single place in the codebase allowed to callconsoledirectly. Legitimate error reporting incatchblocks and error handlers — places where surfacing failures is intentional — was migrated tologger.error/logger.warn. This keeps those signals visible in both dev and production builds while satisfying the linting rule everywhere else.Added a CI-aware
no-consolelint ruleThe ESLint config enforces
no-consoleas an error whenCI=true(set automatically by GitHub Actions) and off locally. Turning it fully off locally means developers see no IDE warnings and can useconsole.debug|log|infofreely during development without any friction — the rule only activates when it matters, at merge time. The build script already runsnpm run lintas part of the frontend build, so no CI pipeline changes were needed.Alternatives considered
Extending the logger with all console methods and keeping
no-consolealways onOne alternative considered was extending
loggerto exposedebug,log, andinfo— stripping those methods in production builds viaimport.meta.env.PROD— and enablingno-consoleas an error everywhere, forcing all output through the logger.This was not pursued for two reasons:
import.meta.env.PRODisfalse, sologger.debug()would still produce output during CI test runs. Suppressing it would require addingimport.meta.env.VITESTawareness to the logger — making a production module aware of the test environment, which is the wrong direction.no-consolealways on, the only escape for test files would be importingsrc/logger.ts— an application module — just to produce debug output. This ties test infrastructure to the System Under Test and compromises test isolation.The current approach avoids both issues: the lint gate runs before tests execute, so noisy output never reaches the test step regardless of environment.
Reviewer Checklist