Skip to content

feat: define reporting service contracts and dispatchers#1224

Open
alexs-mparticle wants to merge 15 commits intodevelopmentfrom
feat/reporting-service-migration-core
Open

feat: define reporting service contracts and dispatchers#1224
alexs-mparticle wants to merge 15 commits intodevelopmentfrom
feat/reporting-service-migration-core

Conversation

@alexs-mparticle
Copy link
Copy Markdown
Collaborator

@alexs-mparticle alexs-mparticle commented Mar 20, 2026

Summary

  • Defines IErrorReportingService and ILoggingService interfaces in src/reporting/types.ts
  • Adds ErrorReportingDispatcher and LoggingDispatcher for multi-service fan-out
  • Decouples Logger from reporting — Logger is now console-only
  • Removes concrete ReportingLogger implementation (moves to Rokt kit)
  • Removes Rokt-specific URLs from constants
  • Renames src/logging/ to src/reporting/
  • Exposes registerErrorReportingService() and registerLoggingService() on mParticle API

Companion kit PR: mparticle-integrations/mparticle-javascript-integration-rokt#70

Test plan

  • Lint, build, Jest tests pass (495 tests)
  • Verify registration APIs exposed on window.mParticle
  • Verify Logger.error() no longer triggers remote reporting

…dule

- Define IErrorReportingService, ILoggingService, ISDKError, ISDKLogEntry contracts
- Add ErrorReportingDispatcher and LoggingDispatcher for multi-service fan-out
- Decouple Logger from reporting (console-only now)
- Remove concrete ReportingLogger implementation (moves to kit)
- Remove Rokt-specific URLs from constants
- Rename src/logging/ to src/reporting/
- Expose registerErrorReportingService/registerLoggingService on mParticle API
@alexs-mparticle alexs-mparticle requested a review from a team as a code owner March 20, 2026 20:45
@cursor
Copy link
Copy Markdown

cursor bot commented Mar 20, 2026

PR Summary

Medium Risk
Medium risk because it refactors cross-cutting logging/reporting behavior and removes the built-in remote ReportingLogger, which could change what errors get surfaced or reported if integrations don’t register replacement services.

Overview
Refactors SDK reporting by removing the built-in ReportingLogger (and its loggingUrl/errorUrl configuration and constants) and making Logger strictly console-only (Logger.error() no longer triggers any reporting side effects).

Introduces structured reporting contracts in src/reporting/types.ts plus ErrorReportingDispatcher/LoggingDispatcher fan-out dispatchers, wires them into mp-instance (including Rokt init) and adds public registration hooks (_registerErrorReportingService, _registerLoggingService) on window.mParticle/instance manager.

Updates IdentityAPIClient and RoktManager to emit console logs and separately send structured errors/warnings (e.g., identity request failures and identity mismatch warnings) through the new dispatchers, and revises tests accordingly.

Written by Cursor Bugbot for commit e1b78da. This will update automatically on new commits. Configure here.

@alexs-mparticle alexs-mparticle marked this pull request as draft March 20, 2026 20:55
- Add optional chaining for _ErrorReportingDispatcher in identityApiClient
  so tests without a mock dispatcher don't crash
- Add registerErrorReportingService and registerLoggingService to the
  expected public API keys in instance manager test
…ning

Reverts optional chaining on _ErrorReportingDispatcher.report() which
was masking potential bugs. Instead, properly adds ErrorReportingDispatcher
instances to all mock mpInstance objects in identity API client tests.
…uctor

- Wrap each service call in try-catch in ErrorReportingDispatcher and
  LoggingDispatcher so one failing service doesn't break fan-out
- Move dispatcher instantiation from runPreConfigFetchInitialization to
  mParticleInstance constructor so registration works before init()
- Destructure errorReporter in identityApiClient for cleaner usage
Rename registerErrorReportingService/registerLoggingService to
_registerErrorReportingService/_registerLoggingService to signal
these are internal APIs consumed by kits, not public.
Pass ErrorReportingDispatcher and LoggingDispatcher into RoktManager.init()
from mp-instance. Add INFO log on kit attach (ROKT_KIT_ATTACHED) and
WARNING reports on identity mismatch (IDENTITY_MISMATCH) alongside
existing logger.warning calls. Add new error codes to reporting types.
… mocks

The identity API client test mocks were missing _ErrorReportingDispatcher,
causing a TypeError when report() was called on 5xx errors. Added optional
chaining to the call site and added the mock to both test cases.
@alexs-mparticle alexs-mparticle marked this pull request as ready for review March 24, 2026 15:12
Merge development into feat/reporting-service-migration-core,
resolving conflicts in dist/ bundle files by accepting development's
versions (CI will regenerate these after merge).

this.loggingService?.log({
message: 'RoktManager: Kit attached, Rokt is ready',
code: ErrorCodes.ROKT_KIT_ATTACHED,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this be an errorcode?

const accountId = '9876543210';
const integrationName = 'test-integration';
describe('Logger is decoupled from reporting', () => {
it('Logger.error() does not trigger any reporting', () => {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This test doesn't seem to do what you're claiming it does. I'd remove...all it does is test that no error is thrown. The test below this proves that logger is decoupled from reporting

Comment on lines +84 to +87
it('log() is a no-op when no services are registered', () => {
// Should not throw
dispatcher.log({
message: 'test',
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Test name is awkward here. also isn't doing what you are asserting. (There is no assertion). This is also obvious, but how about

const mockService: ILoggingService = { log: jest.fn() };
      // Intentionally NOT registering mockService on this dispatcher                                                                                                                           
  
      dispatcher.log({ message: 'test' });                                                                                                                                                      
                             
      expect(mockService.log).not.toHaveBeenCalled();       

Copy link
Copy Markdown
Member

@rmi22186 rmi22186 left a comment

Choose a reason for hiding this comment

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

minor nits

rmi22186 and others added 2 commits April 3, 2026 15:21
The TODO indicated this cast should be removed once removeCCPAState was
removed. Since removeCCPAState is being removed in this PR, the cast is
no longer needed.

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

sonarqubecloud bot commented Apr 3, 2026

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

UNHANDLED_EXCEPTION: 'UNHANDLED_EXCEPTION',
IDENTITY_REQUEST: 'IDENTITY_REQUEST',
IDENTITY_MISMATCH: 'IDENTITY_MISMATCH',
ROKT_KIT_ATTACHED: 'ROKT_KIT_ATTACHED',
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Informational event misclassified as an error code

Low Severity

ROKT_KIT_ATTACHED is defined in the ErrorCodes enum but represents a successful informational event ("Kit attached, Rokt is ready"), not an error or warning. It's only used in loggingService?.log(...), the informational logging path. Placing a success event in an enum named ErrorCodes is misleading and could confuse consumers implementing ILoggingService or IErrorReportingService contracts. As the reviewer noted, this doesn't belong in ErrorCodes.

Additional Locations (1)
Fix in Cursor Fix in Web

value: { userAgent: 'test-user-agent' }
// Logger.error() should only output to console - no reporting side effects
// This verifies the decoupling is complete
expect(() => logger.error('test error')).not.toThrow();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Test asserts no-throw instead of verifying decoupling

Low Severity

The test named "Logger.error() does not trigger any reporting" only asserts not.toThrow(). It creates no mock services and makes no assertions about reporting behavior, so it doesn't actually verify the decoupling claim in its name. The subsequent test already proves the decoupling properly, making this test redundant and misleading.

Fix in Cursor Fix in Web

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