-
Notifications
You must be signed in to change notification settings - Fork 85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: move error reporting functionality to the core module #1984
Conversation
📝 WalkthroughWalkthroughThis pull request introduces significant changes to error handling and logging mechanisms across the RudderStack JavaScript SDK. The primary focus is on removing the Bugsnag and ErrorReporting plugins while refactoring error management to be more consistent and robust. Key modifications include changing optional error handlers and loggers to required dependencies, simplifying error handling logic, and removing deprecated plugin implementations. The changes aim to streamline error reporting and enhance the overall reliability of the SDK's error management infrastructure. Changes
Sequence DiagramsequenceDiagram
participant SDK as RudderStack SDK
participant ErrorHandler as Error Handler
participant HttpClient as HTTP Client
participant Logger as Logger
SDK->>ErrorHandler: Encounter Error
ErrorHandler->>ErrorHandler: Normalize Error
ErrorHandler->>HttpClient: Prepare Error Payload
HttpClient->>HttpClient: Send Error Data
ErrorHandler->>Logger: Log Error Details
ErrorHandler->>SDK: Error Processed
Possibly related PRs
Suggested Reviewers
Finishing Touches
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (27)
packages/analytics-js/src/services/ErrorHandler/ErrorHandler.ts (6)
20-27
: **Maintain consistent naming for utility imports **The utility functions (
createNewBreadcrumb
,getErrInstance
, etc.) are well-named. To keep code consistent, consider grouping or re-exporting them from a single utility index if multiple files also use them.
39-42
: **Initialize error listeners in the constructor **Attaching error listeners upon instantiation might surprise consumers of this class if they expect to configure it first. Consider adding an optional flag or a separate initialization method for clarity.
54-54
: **Handle unhandledrejection thoroughly **Confirm that promise rejection reasons are properly handled for both standard and custom errors.
Need help crafting robust fallback logic for less common cases?
75-76
: **Error prefix usage **Appending
LOG_CONTEXT_SEPARATOR
in the prefix is a nice approach. For clarity, confirm that context and customMessage are always strings.
83-83
: **Optional check for user consent **If user privacy settings might prevent sending certain data, consider hooking an additional consent check here to respect user preferences.
141-141
: **Default handler instantiation **
defaultErrorHandler
is helpful for places that need a preconfigured handler. If you ever need a custom logger or client, ensure they can override this default easily.packages/analytics-js/src/services/ErrorHandler/utils.ts (4)
16-16
: **JSON utility usage **
stringifyWithoutCircular
is handy. Consider adding logging in case cyclical references are dropped, to ensure vital data isn't unintentionally lost.
30-41
: **Address the useless case clause **The switch statement includes
case ErrorType.HANDLEDEXCEPTION:
and adefault:
clause that both return the same thing. You can simplify:switch (errorType) { case ErrorType.UNHANDLEDEXCEPTION: { const { error } = err as ErrorEvent; return error || err; } case ErrorType.UNHANDLEDREJECTION: { return (err as PromiseRejectionEvent).reason; } - case ErrorType.HANDLEDEXCEPTION: default: return err; }
🧰 Tools
🪛 Biome (1.9.4)
[error] 39-39: Useless case clause.
because the default clause is present:
Unsafe fix: Remove the useless case.
(lint/complexity/noUselessSwitchCase)
76-119
: **Rich payload creation for error events **The multi-level metadata helps debugging. If large, consider selectively omitting some details in production to minimize payload size.
172-172
: **Ensure consistent export ordering **Wrapping all utility exports together is helpful. If the module grows, consider grouping them thematically for readability.
packages/analytics-js-common/src/types/ErrorHandler.ts (1)
9-9
: Context parameter naming consistency.
onError
acceptscontext?: string, customMessage?: string, errorType?: string
. For clarity, consider reordering or renaming parameters if they’re triggered in code to ensure consistent usage across the codebase.packages/analytics-js/src/services/ErrorHandler/constants.ts (1)
27-27
: Preemptively define filtering logic for error messages.
ERROR_MESSAGES_TO_BE_FILTERED
is currently empty. Consider documenting its usage, the criteria for filtering, and how these messages will be handled downstream.packages/analytics-js/src/services/ErrorHandler/constant.ts (3)
1-4
: Use caution when duplicating code across multiple constants files.
SDK_FILE_NAME_PREFIXES
in this file appears to replicate similar logic fromconstants.ts
. If both files persist, ensure they remain in sync. Alternatively, consider consolidating them into a single shared constants file.
8-21
: Maintain separate logic for sensitive data keys.
APP_STATE_EXCLUDE_KEYS
helps protect PII or sensitive data. Ensure that newly identified keys are appended here to remain consistent with the broader data-protection strategy.
27-35
: Export handles new constants cohesively.Overall, exporting these constants as a single batch is straightforward. Consider adding JSDoc for each constant so future developers quickly understand the rationale behind them.
packages/analytics-js-common/src/types/Metrics.ts (1)
33-33
: Newtype
inapp
object can clarify environment.Adding a
type
field is helpful for environment or deployment identification. It may be useful to define a small set of valid types or an enum, if feasible.packages/analytics-js-common/src/types/HttpClient.ts (1)
68-68
: Newinit
method promotes flexible error handling configuration.Introducing
init(errorHandler: IErrorHandler)
decouples the error handler from constructor logic. Ensure usage examples or documentation are updated so developers know to callinit
before making requests.packages/analytics-js/.size-limit.mjs (2)
39-39
: Increased size limit for Core - Modern - NPM (CJS)
Same remark as above: confirm that the additional size is justified. Reducing unused code might help offset this size jump.
50-50
: Increased size limit for Core - Modern - CDN
As CDN bundles should be as lean as possible, carefully watch for future size creep to preserve fast load times.packages/analytics-js/src/services/HttpClient/HttpClient.ts (1)
32-35
: Defer error handler initialization
The newinit
method provides a clean mechanism for setting the error handler. Ensure this method is called during application startup to avoid unhandled errors.packages/analytics-js/src/services/ErrorHandler/event/event.ts (4)
12-13
: RenamenormaliseFunctionName
tonormalizeFunctionName
for consistency.
To maintain consistent spelling throughout the codebase, consider using the more commonly spelled "normalize".-const normaliseFunctionName = (name: string) => (/^global code$/i.test(name) ? GLOBAL_CODE : name); +const normalizeFunctionName = (name: string) => (/^global code$/i.test(name) ? GLOBAL_CODE : name);
68-77
: Avoid repeated[object Error]
checks if performance is critical.
isError
function is thorough, but in some environments repeatedObject.prototype.toString.call
can be slow. If performance in error handling is critical, consider caching or simpler checks.
79-90
: Log usage ofmaybeError
prior to callingstringifyWithoutCircular
.
In the failure branch (line 85), you logundefined
ifmaybeError
is not a valid error. Consider usingmaybeError
in the place oferror
to reduce confusion in logs.-logger?.warn(NON_ERROR_WARNING(ERROR_HANDLER, stringifyWithoutCircular(error))); +logger?.warn(NON_ERROR_WARNING(ERROR_HANDLER, stringifyWithoutCircular(maybeError)));
92-101
: Improve error type coverage forcreateBugsnagException
.
Wrapping theErrorStackParser.parse
in a try-catch is great. If you’re open to enhancement, consider logging the parse failure to aid debugging.packages/analytics-js/src/components/configManager/ConfigManager.ts (1)
156-156
: Ensure new error object is descriptive.
Instantiating a newError(SOURCE_CONFIG_RESOLUTION_ERROR)
is fine. Just confirm the user or logs have enough context to react (like an HTTP status).packages/analytics-js/__tests__/services/ErrorHandler/utils.test.ts (2)
438-438
: Remove console logging from tests to avoid noise in production logs.
Theconsole.log(JSON.stringify(enhancedError))
statement might clutter CI or production logs. Consider removing it or using the test runner's debug logging if needed.
594-602
: Clarify contradictory test naming.
There are two test cases reported as "should return true for Error argument value" (lines 594 and 599), but they produce different results. Consider renaming or adding details to highlight the distinct behavior under test.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (51)
packages/analytics-js-common/__mocks__/ErrorHandler.ts
(1 hunks)packages/analytics-js-common/__mocks__/HttpClient.ts
(1 hunks)packages/analytics-js-common/src/services/ExternalSrcLoader/types.ts
(2 hunks)packages/analytics-js-common/src/types/ErrorHandler.ts
(1 hunks)packages/analytics-js-common/src/types/HttpClient.ts
(1 hunks)packages/analytics-js-common/src/types/Metrics.ts
(3 hunks)packages/analytics-js-common/src/types/PluginsManager.ts
(0 hunks)packages/analytics-js-common/src/types/Source.ts
(1 hunks)packages/analytics-js-plugins/__mocks__/state.ts
(0 hunks)packages/analytics-js-plugins/__tests__/deviceModeTransformation/index.test.ts
(1 hunks)packages/analytics-js-plugins/__tests__/xhrQueue/index.test.ts
(1 hunks)packages/analytics-js-plugins/rollup.config.mjs
(0 hunks)packages/analytics-js-plugins/src/bugsnag/constants.ts
(0 hunks)packages/analytics-js-plugins/src/bugsnag/index.ts
(0 hunks)packages/analytics-js-plugins/src/bugsnag/logMessages.ts
(0 hunks)packages/analytics-js-plugins/src/bugsnag/utils.ts
(0 hunks)packages/analytics-js-plugins/src/errorReporting/event/event.ts
(0 hunks)packages/analytics-js-plugins/src/errorReporting/event/utils.ts
(0 hunks)packages/analytics-js-plugins/src/errorReporting/index.ts
(0 hunks)packages/analytics-js-plugins/src/errorReporting/logMessages.ts
(0 hunks)packages/analytics-js-plugins/src/errorReporting/types.ts
(0 hunks)packages/analytics-js-plugins/src/index.ts
(0 hunks)packages/analytics-js-plugins/src/shared-chunks/common.ts
(0 hunks)packages/analytics-js/.size-limit.mjs
(1 hunks)packages/analytics-js/__mocks__/remotePlugins/Bugsnag.ts
(0 hunks)packages/analytics-js/__mocks__/remotePlugins/ErrorReporting.ts
(0 hunks)packages/analytics-js/__tests__/services/ErrorHandler/utils.test.ts
(1 hunks)packages/analytics-js/rollup.config.mjs
(1 hunks)packages/analytics-js/src/app/RudderAnalytics.ts
(0 hunks)packages/analytics-js/src/components/capabilitiesManager/CapabilitiesManager.ts
(1 hunks)packages/analytics-js/src/components/capabilitiesManager/detection/adBlockers.ts
(2 hunks)packages/analytics-js/src/components/capabilitiesManager/types.ts
(1 hunks)packages/analytics-js/src/components/configManager/ConfigManager.ts
(3 hunks)packages/analytics-js/src/components/core/Analytics.ts
(2 hunks)packages/analytics-js/src/components/eventManager/EventManager.ts
(1 hunks)packages/analytics-js/src/components/eventRepository/EventRepository.ts
(2 hunks)packages/analytics-js/src/components/pluginsManager/PluginsManager.ts
(0 hunks)packages/analytics-js/src/components/pluginsManager/bundledBuildPluginImports.ts
(0 hunks)packages/analytics-js/src/components/pluginsManager/defaultPluginsList.ts
(0 hunks)packages/analytics-js/src/components/pluginsManager/federatedModulesBuildPluginImports.ts
(0 hunks)packages/analytics-js/src/components/pluginsManager/pluginNames.ts
(1 hunks)packages/analytics-js/src/constants/logMessages.ts
(4 hunks)packages/analytics-js/src/services/ErrorHandler/ErrorHandler.ts
(2 hunks)packages/analytics-js/src/services/ErrorHandler/constant.ts
(1 hunks)packages/analytics-js/src/services/ErrorHandler/constants.ts
(2 hunks)packages/analytics-js/src/services/ErrorHandler/event/event.ts
(1 hunks)packages/analytics-js/src/services/ErrorHandler/event/types.ts
(1 hunks)packages/analytics-js/src/services/ErrorHandler/processError.ts
(0 hunks)packages/analytics-js/src/services/ErrorHandler/utils.ts
(3 hunks)packages/analytics-js/src/services/HttpClient/HttpClient.ts
(2 hunks)packages/analytics-js/src/types/remote-plugins.d.ts
(0 hunks)
💤 Files with no reviewable changes (23)
- packages/analytics-js-plugins/src/errorReporting/logMessages.ts
- packages/analytics-js-plugins/src/shared-chunks/common.ts
- packages/analytics-js-plugins/rollup.config.mjs
- packages/analytics-js-plugins/src/errorReporting/types.ts
- packages/analytics-js-plugins/src/index.ts
- packages/analytics-js/src/components/pluginsManager/defaultPluginsList.ts
- packages/analytics-js/src/types/remote-plugins.d.ts
- packages/analytics-js/mocks/remotePlugins/Bugsnag.ts
- packages/analytics-js/mocks/remotePlugins/ErrorReporting.ts
- packages/analytics-js-plugins/src/errorReporting/event/utils.ts
- packages/analytics-js-common/src/types/PluginsManager.ts
- packages/analytics-js/src/components/pluginsManager/bundledBuildPluginImports.ts
- packages/analytics-js/src/components/pluginsManager/federatedModulesBuildPluginImports.ts
- packages/analytics-js/src/components/pluginsManager/PluginsManager.ts
- packages/analytics-js-plugins/src/errorReporting/event/event.ts
- packages/analytics-js-plugins/mocks/state.ts
- packages/analytics-js-plugins/src/errorReporting/index.ts
- packages/analytics-js-plugins/src/bugsnag/index.ts
- packages/analytics-js/src/services/ErrorHandler/processError.ts
- packages/analytics-js-plugins/src/bugsnag/logMessages.ts
- packages/analytics-js-plugins/src/bugsnag/constants.ts
- packages/analytics-js/src/app/RudderAnalytics.ts
- packages/analytics-js-plugins/src/bugsnag/utils.ts
🧰 Additional context used
📓 Learnings (4)
packages/analytics-js-plugins/__tests__/deviceModeTransformation/index.test.ts (1)
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1708
File: packages/analytics-js-plugins/__tests__/deviceModeTransformation/index.test.ts:10-11
Timestamp: 2024-11-12T15:14:33.334Z
Learning: The misuse of `IHttpClient` in type assertions within the file `packages/analytics-js-plugins/__tests__/deviceModeTransformation/index.test.ts` has been corrected by the user.
packages/analytics-js/src/services/ErrorHandler/event/event.ts (1)
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1907
File: packages/analytics-js/src/services/ErrorHandler/ErrorHandler.ts:172-174
Timestamp: 2024-11-12T15:14:23.319Z
Learning: The function `onError` in `packages/analytics-js/src/services/ErrorHandler/ErrorHandler.ts` is acceptable as currently implemented, and refactoring suggestions are not required unless necessary.
packages/analytics-js/src/constants/logMessages.ts (2)
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1823
File: packages/analytics-js-common/src/types/LoadOptions.ts:175-192
Timestamp: 2024-11-12T15:14:23.319Z
Learning: In this project, deprecated properties may still be used internally to provide backward compatibility for users, as the same types are used for both public-facing APIs and the internal codebase.
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1823
File: packages/analytics-js-common/src/types/LoadOptions.ts:0-0
Timestamp: 2024-11-12T15:14:23.319Z
Learning: In the `packages/analytics-js-common/src/types/LoadOptions.ts` file, the `dataplanes` property within the `SourceConfigResponse` type has been removed as it is no longer necessary.
packages/analytics-js-common/src/services/ExternalSrcLoader/types.ts (1)
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1823
File: packages/analytics-js-common/src/services/ExternalSrcLoader/jsFileLoader.ts:0-0
Timestamp: 2024-11-12T15:14:33.334Z
Learning: The `onerror` handler for script elements has the signature `(event: Event | string, source?: string, lineno?: number, colno?: number, error?: Error)`.
🪛 Biome (1.9.4)
packages/analytics-js/src/services/ErrorHandler/utils.ts
[error] 39-39: Useless case clause.
because the default clause is present:
Unsafe fix: Remove the useless case.
(lint/complexity/noUselessSwitchCase)
🔇 Additional comments (74)
packages/analytics-js/src/components/pluginsManager/pluginNames.ts (1)
28-28
: Confirm deprecation cleanup for the ErrorReporting
plugin.
Marking ErrorReporting
as deprecated here is consistent with the PR’s objective of relocating or removing the plugin’s operations. Ensure that:
- No active references to
ErrorReporting
remain in the codebase. - Tests and build steps that depended on this plugin have been properly updated.
Below is a script you can run to confirm that usage references to ErrorReporting
have been removed or replaced:
packages/analytics-js/src/services/ErrorHandler/ErrorHandler.ts (9)
14-16
: **Use descriptive constants as intended **
These constants (BREADCRUMB_ERROR
, FAILED_ATTACH_LISTENERS_ERROR
, HANDLE_ERROR_FAILURE
) clearly convey the purpose of each message.
28-28
: **Event-based import looks good **
Importing createBugsnagException
and normalizeError
from a dedicated event
module is a clean separation of responsibilities.
35-35
: **Interface alignment **
Implementing IErrorHandler
ensures consistency across the codebase for error-handling functionality.
48-48
: **Ensure correct ErrorEvent usage **
Make sure that the event
object is always an ErrorEvent
or a generic Event
. Some older browsers may not dispatch the exact same structure.
Would you like to check compatibility with older browsers or gather additional logs?
58-58
: **Fallback log for environments without addEventListener **
Providing a fallback log with this.logger?.error()
is appropriate for older environments.
68-71
: **Robust error normalization usage **
Using getErrInstance
and normalizeError
ensures consistent error structures before handling or reporting.
78-80
: **Early return for non-Rudder errors **
Checking isRudderSDKError
prevents reporting extraneous errors to your metrics service.
105-117
: **Conditional console error logging **
Only logging handled exceptions to the console helps keep logs clean. This block also gracefully handles unknown errors. Good approach.
130-136
: **Breadcrumb management **
Creating and storing breadcrumbs in the application state is a sensible approach that simplifies the path to external error reporting.
packages/analytics-js/src/services/ErrorHandler/utils.ts (11)
13-13
: **Explicit import for Exception **
Defining a clear Exception
type clarifies function signatures and helps avoid confusion with built-in Error
.
17-17
: **CDN constant usage **
Using CDN_INT_DIR
from a shared constant fosters a single source of truth for CDN integration directories.
18-18
: **UUID usage **
generateUUID
usage is ideal for deduplicating errors or grouping them in logs.
23-24
: **Filtering known error messages **
ERROR_MESSAGES_TO_BE_FILTERED
and NOTIFIER_NAME
usage is appropriate for ignoring specific known events and naming your notifier.
45-49
: **Minimal breadcrumb metadata **
A default empty object for metaData
prevents undefined issues when referencing breadcrumb details later.
68-71
: **Descriptive parameter names **
Renaming the parameter to exception
instead of payload
clarifies the type of data being handled.
72-75
: **State deconstruction **
Extracting context, lifecycle, session, etc., early leads to a cleaner approach when building error payloads.
124-124
: **Adaptive doc comment **
No actionable feedback here; this doc clarifies the function usage well.
127-128
: **Filtering known false positives **
isAllowedToBeNotified
ensures you skip known benign errors. This prevents unnecessary noise in error reporting.
132-132
: **Doc block clarity **
The doc block is concise and aligned with code changes.
135-136
: **SDK file check **
isRudderSDKError
logic is robust. Checking file path ensures you only capture internal errors.
packages/analytics-js/src/services/ErrorHandler/event/types.ts (1)
1-6
: **FrameType introduction **
Defining FrameType
clarifies the structure of stack frames for reporting. Make sure any transformations of stack frames align with this schema.
packages/analytics-js-common/src/types/Source.ts (1)
18-18
: **New optional property: name **
Adding name: string
can be beneficial for more explicit source identification. Confirm that all existing code references or future expansions correctly handle non-empty string values here.
Do you want a quick script to verify all references to the Source
type are updated accordingly?
packages/analytics-js-common/__mocks__/ErrorHandler.ts (2)
1-2
: **Consistent type usage for mocks **
Importing IErrorHandler
ensures the mock remains aligned with real usage.
8-8
: **New httpClient property **
Replacing the buffer with an httpClient
property keeps the mock class consistent with the real ErrorHandler
class updates.
packages/analytics-js-common/src/services/ExternalSrcLoader/types.ts (2)
14-14
: Optional property is consistent with usage.
errorHandler
is marked optional. Verify that all consumer code handles the possibility of it being undefined before usage.
1-1
: Confirm correctness of imported interface names.
Ensure that IErrorHandler
is properly located at '../../types/ErrorHandler'
.
Run the following script to confirm:
✅ Verification successful
Import statement correctly references the IErrorHandler
interface
The verification confirms that both IErrorHandler
interface and ErrorState
type are properly defined in the referenced file packages/analytics-js-common/src/types/ErrorHandler.ts
. The import statement is correct and matches the actual declarations in the target file.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that IErrorHandler is defined in the referenced file.
rg -A 10 'interface IErrorHandler' packages/analytics-js-common/src/types/ErrorHandler.ts
Length of output: 420
packages/analytics-js/src/components/capabilitiesManager/types.ts (1)
7-7
: 🛠️ Refactor suggestion
Mandatory requirement of errorHandler
.
Switching from optional to required is a breaking contract change. Ensure all existing consumers provide this property.
Would you like me to scan the codebase for all ICapabilitiesManager
implementations to confirm compliance?
packages/analytics-js-common/__mocks__/HttpClient.ts (1)
13-13
: New init
method mock.
This mock is aligned with the new initialization pattern. Confirm that the init
method is consistently invoked in tests to avoid uninitialized states.
packages/analytics-js-common/src/types/ErrorHandler.ts (1)
7-7
: Emphasize clarity of httpClient
usage.
Including httpClient
in the error handler fosters a single integration point for reporting. Just ensure no circular dependencies occur (e.g., httpClient
depends on IErrorHandler
while IErrorHandler
also depends on httpClient
).
packages/analytics-js/src/services/ErrorHandler/constants.ts (3)
23-23
: Confirm naming consistency and downstream references.
Renaming NOTIFIER_NAME
to a more generic label is acceptable, but please verify all references to ensure the updated name does not break any telemetry or usage patterns reliant on the old string value.
24-24
: Ensure placeholder replacement at build time.
Replacing the GitHub URL with __REPOSITORY_URL__
is fine as a placeholder, but confirm that the build or deployment process substitutes this placeholder correctly before release. Otherwise, debugging or error contexts may lack the correct URL reference.
37-37
: Exporting ERROR_MESSAGES_TO_BE_FILTERED
for future usage.
Exporting this new constant appears consistent with the broader shift to filter or process certain errors. Looks good for modular use across the codebase.
packages/analytics-js/src/services/ErrorHandler/constant.ts (3)
6-7
: Development hosts list looks correct.
The DEV_HOSTS
array is a good approach for isolating dev or test environments. If more environments are introduced, consider adding them here to keep logic consistent.
22-22
: Timeout threshold looks standard for HTTP operations.
REQUEST_TIMEOUT_MS = 10 * 1000
is reasonable for most analytics requests. Confirm that upstream or downstream usage doesn’t require a configurable approach for edge cases.
23-25
: Align metadata with repository references.
NOTIFIER_NAME
, SDK_GITHUB_URL
, and SOURCE_NAME
are consistent with the core library’s naming scheme. Please verify these references match your actual build-time replacements if any environment-based logic is employed.
packages/analytics-js-common/src/types/Metrics.ts (5)
16-16
: Confirm backward compatibility for payloadVersion
.
Adding payloadVersion
ensures versioning for error payloads, but confirm that clients handling older versions remain unaffected. If version checking logic is needed, implement it in the error processing pipeline.
22-22
: Update references from ErrorEventType
to ErrorEvent
.
Switching to ErrorEvent[]
helps unify the event structure. Double-check any code previously referencing ErrorEventType
so that it’s replaced or removed as needed.
25-25
: Catch potential edge cases in new ErrorEvent
structure.
ErrorEvent
now mandates exceptions
and unhandled
, among others. Ensure that all code paths set these fields appropriately to avoid partial or malformed events.
50-50
: New name
property in user
.
The additional name
property can enhance user context in error reports. Validate that PII or privacy concerns are addressed if storing real names.
67-72
: Exception
interface redefined but logically unchanged.
The Exception
interface remains consistent with typical error structures. If you foresee expansions (e.g. new fields for categorization or error grouping), that can be added in a future iteration.
packages/analytics-js/src/components/capabilitiesManager/detection/adBlockers.ts (2)
6-6
: Enforce required error handler usage
Making the errorHandler
a required parameter will ensure that any errors are consistently handled, thereby improving the application's resilience.
16-17
: Ensure error handler is initialized first
Calling httpClient.init(errorHandler)
immediately after construction is crucial for guaranteeing that subsequent calls to httpClient
will have proper error handling set up.
packages/analytics-js/src/components/eventManager/EventManager.ts (1)
71-73
: Simplify error handling flow
Removing the shouldAlwaysThrow
parameter streamlines error handling. However, ensure that any previous usage scenarios of this flag elsewhere in the codebase no longer rely on it.
packages/analytics-js/.size-limit.mjs (2)
33-33
: Increased size limit for Core - Modern - NPM (ESM)
Raising the limit by 2.5 KiB may be acceptable if it results from necessary functionality. However, keep an eye on bundle growth to ensure it remains within acceptable thresholds.
45-45
: Increased size limit for Core - Modern - NPM (UMD)
Ensure that any newly introduced features or dependencies which increased this limit are truly essential for the updated functionality.
packages/analytics-js/src/services/HttpClient/HttpClient.ts (2)
27-27
: Refined constructor
By removing the errorHandler
parameter, you simplify object construction, making the client more flexible. This approach aligns well with the separation of concerns principle.
112-112
: Confirm default client usage
Now that defaultHttpClient
omits the error handler, verify that init
is called on it before making requests. Otherwise, a missing error handler could lead to unprotected error paths.
✅ Verification successful
Let me search for the initialization of the defaultHttpClient to verify if it's properly initialized before use.
Let me check the Analytics class initialization since it's the main component using defaultHttpClient.
Let me try a different approach to find the Analytics class initialization.
Based on the code analysis, I can now provide a final response:
defaultHttpClient
initialization is properly handled
The defaultHttpClient
is safely initialized before use. In the Analytics class constructor, it's assigned as this.httpClient = defaultHttpClient
, and in the loadConfig
method, the auth header is set before any requests are made: this.httpClient.init(this.errorHandler)
. The initialization flow is:
- Analytics constructor sets
this.httpClient = defaultHttpClient
onBrowserCapabilitiesReady
callsprepareInternalServices
prepareInternalServices
initializes all dependent services with the httpClientloadConfig
sets auth headers before making requests
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Verifying all references to defaultHttpClient
# to ensure the init() method is called prior to usage
rg -A 3 "defaultHttpClient"
Length of output: 19103
Script:
#!/bin/bash
# Search for HttpClient init method calls
ast-grep --pattern 'httpClient.init($_)'
Length of output: 159
Script:
#!/bin/bash
# Search for Analytics class constructor and initialization
ast-grep --pattern 'class Analytics {
$$$
constructor() {
$$$
}
$$$
}'
Length of output: 65984
Script:
#!/bin/bash
# Search for Analytics class in the newer codebase
ast-grep --pattern 'class Analytics {
$$$
constructor() {
$$$
this.httpClient = $_
$$$
}
$$$
}'
Length of output: 22871
packages/analytics-js/src/services/ErrorHandler/event/event.ts (5)
1-9
: Consider organizing imports with identification of usage.
While the import statements look good, you might want to confirm whether all the imported utilities and types are actually used in this file. This ensures leaner bundles and clearer dependency management.
20-35
: Ensure stackframe properties align with all possible runtime errors.
When formatting the stackframe, confirm that unexpected error shapes will not cause unhandled issues. Consider additional null or undefined checks for file details.
37-37
: Optimize string check.
ensureString
is straightforward, but ensure that performance is acceptable if used heavily in tight loops. Otherwise it looks fine.
39-60
: Validate potential edge cases in createException
.
The approach of filtering empty stack frames is good. However, double-check any possible scenario where an error’s class or message might be missing altogether.
62-66
: Good defensive check for hasStack
.
This function thoroughly checks multiple stack notations. Makes your error parser robust across different browsers.
packages/analytics-js/src/components/capabilitiesManager/CapabilitiesManager.ts (2)
40-40
: Mandatory errorHandler
ensures consistent error handling.
This shift from optional to required fosters more reliable error capturing. Ensure all call sites provide a valid errorHandler
.
43-43
: Leverage constructor DI for consistent usage of errorHandler
.
The new constructor pattern enforces dependency injection of errorHandler
. This is a good design approach for testability.
packages/analytics-js/src/components/eventRepository/EventRepository.ts (2)
53-59
: Constructor now requires httpClient
.
Requiring an HTTP client in the constructor promotes a clear separation of concerns. Confirm that all existing call sites pass in the correct implementation.
216-218
: Removal of shouldAlwaysThrow
simplifies error handling flow.
This streamlines the logic and ensures consistent usage of this.errorHandler.onError
. Double-check that no existing logic depended on conditional throwing.
packages/analytics-js/src/components/configManager/ConfigManager.ts (3)
123-125
: onError
signature simplification.
Removing shouldAlwaysThrow
helps unify how errors are processed. Confirm that no upstream calls require a forced throw scenario.
151-151
: Proper error logging on config parse failures.
Calling onError
here is appropriate for capturing parse issues. Just verify any specialized logs or metrics if config parse errors are frequent.
177-177
: Addition of source name
to the state.
This is helpful for clarity. Ensure usage in UI or logs is thoroughly tested.
packages/analytics-js-plugins/__tests__/deviceModeTransformation/index.test.ts (1)
8-8
: Good adoption of the shared defaultHttpClient mock.
This import aligns with the standardized testing approach for network interactions, reducing duplication across files. No issues observed with usage.
packages/analytics-js-plugins/__tests__/xhrQueue/index.test.ts (1)
9-9
: Consistent usage of defaultHttpClient mock.
Switching to the shared mock improves maintainability across test files. Great job consolidating the mock implementation in a single place.
packages/analytics-js/rollup.config.mjs (1)
190-190
: Check for fallback logic when the repository URL is missing in package.json.
If pkg.repository
or its url
field isn't defined, this replacement may fail or yield unexpected results at build time. Consider adding a fallback or a check to ensure url
is always available.
packages/analytics-js/src/constants/logMessages.ts (7)
11-11
: Introduction of Nullable type.
Using Nullable<string>
is a clean approach to handling optional error strings. This aligns with the existing type definitions in @rudderstack/analytics-js-common/types/Nullable
.
36-37
: New NON_ERROR_WARNING constant.
This function clarifies when a non-exception situation is logged, helping differentiate real errors from benign warnings.
39-40
: FAILED_ATTACH_LISTENERS_ERROR constant.
Defining a dedicated error message for listener attachment failures makes debugging more straightforward.
42-43
: BREADCRUMB_ERROR constant.
Providing a distinct message for breadcrumb logging failures helps isolate and troubleshoot potential misconfigurations in error tracking mechanisms.
45-46
: HANDLE_ERROR_FAILURE constant.
A separate error message for error handling failures adds clarity in logs. Ensures that any problems in overall error flow are surfaced.
277-277
: Export of HANDLE_ERROR_FAILURE.
Ensuring this newly added constant is exported from this file allows other modules to leverage the same standardized error message.
326-328
: Exporting new error/warning constants.
Exporting BREADCRUMB_ERROR
, NON_ERROR_WARNING
, and FAILED_ATTACH_LISTENERS_ERROR
centralizes these messages for uniform usage across the codebase.
packages/analytics-js/__tests__/services/ErrorHandler/utils.test.ts (2)
399-401
: Be mindful of BigInt usage for legacy browsers [IE11].
Since this test covers a BigInt scenario (BigInt(123)
), please ensure that your target environments support BigInt or the appropriate polyfill.
417-511
: Confirm the intentional retention of Bugsnag references.
There are still functions and tests referencing Bugsnag (getBugsnagErrorEvent
), though the summary indicates that Bugsnag is removed across the codebase. Verify that these references are necessary moving forward or if they should be renamed or removed entirely.
packages/analytics-js/src/components/core/Analytics.ts (2)
102-102
: Check for potential double initialization.
Invoking this.httpClient.init(this.errorHandler);
at construction is fine, but verify that init
is idempotent or guarded against repeated calls to avoid unexpected states.
250-250
: Dependency injection is well organized.
Passing this.httpClient, this.errorHandler, this.logger
into the EventRepository
constructor keeps concerns separated and is a good design move.
packages/analytics-js/src/services/ErrorHandler/ErrorHandler.ts
Outdated
Show resolved
Hide resolved
size-limit report 📦
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (12)
packages/analytics-js/__tests__/components/pluginsManager/PluginsManager.test.ts (1)
67-67
: Test name appears misleading given its current implementation.Although the test is named "should not filter the error reporting plugins if it is configured to load by default," the verification set no longer includes any error reporting plugins. This might confuse future maintainers into expecting a plugin that no longer exists. Consider revising the test name or removing it if the behavior is no longer relevant.
Below is an optional snippet to rename the test, ensuring clarity around what it currently verifies:
- it('should not filter the error reporting plugins if it is configured to load by default', () => { + it('should maintain the default plugin set when error reporting is enabled', () => {packages/analytics-js/__tests__/components/capabilitiesManager/detection/adBlockers.test.ts (1)
16-16
: Ensure comprehensive testing of mockedHttpClient
.The mocked
HttpClient
correctly emulates asynchronous behavior viagetAsyncData
. Check that tests also capture error-handling logic in case of non-network errors, ensuringdefaultErrorHandler
is fully exercised in different scenarios.packages/analytics-js-common/src/utilities/errors.ts (2)
42-55
: Remove the redundantcase operaSourceloc
in theswitch
statement
Because thedefault
case is present, thecase operaSourceloc:
branch is effectively duplicated logic. Removing the redundant case leads to cleaner code:switch (errStack) { case stack: error.stack = `${stack}\n${MANUAL_ERROR_IDENTIFIER}`; break; case stacktrace: error.stacktrace = `${stacktrace}\n${MANUAL_ERROR_IDENTIFIER}`; break; - case operaSourceloc: default: error['opera#sourceloc'] = `${operaSourceloc}\n${MANUAL_ERROR_IDENTIFIER}`; break; }
🧰 Tools
🪛 Biome (1.9.4)
[error] 50-50: Useless case clause.
because the default clause is present:
Unsafe fix: Remove the useless case.
(lint/complexity/noUselessSwitchCase)
58-58
: Potential cross-browser issue
ErrorEvent
may not be supported on older browsers (e.g., IE11). If full cross-browser compatibility is required, consider a fallback mechanism or feature detection before usingnew ErrorEvent
.packages/analytics-js-common/src/utilities/checks.ts (1)
72-81
: Cross-realm edge cases
Usingvalue instanceof Error
may fail for errors originating in a different JavaScript realm (e.g., an iframe). If you need robust cross-iframe error detection, consider additional checks.packages/analytics-js/__tests__/components/eventManager/EventManager.test.ts (1)
46-46
: Explicitly checking forundefined
Verifying thatonError
is called with anundefined
third argument clarifies expected behavior. If this value never varies, consider omitting it or clarifying why it's important in test docs.packages/analytics-js/__tests__/services/ErrorHandler/ErrorHandler.test.ts (1)
136-220
: Skipped test
The.skip
annotation prevents coverage of the scenario where error reporting is enabled for valid errors. If coverage is desired, consider re-enabling the test or clarifying its deactivation in documentation.packages/analytics-js/__tests__/services/ErrorHandler/utils.test.ts (1)
418-418
: Skipping this test could lead to coverage gaps.
Consider removing or enabling thegetBugsnagErrorEvent
test if it's part of the new logic or no longer needed.packages/analytics-js/src/services/ErrorHandler/ErrorHandler.ts (2)
45-45
: Attaching listeners inside the constructor.
This automatically sets up global error handlers—makes sense, but watch for potential side effects if this class is re-instantiated multiple times.
101-113
: Asynchronous error reporting.
LeveraginggetAsyncData
to POST error details is consistent with the new architecture. Consider implementing batch or retry logic if you anticipate high error volume.packages/analytics-js/src/services/ErrorHandler/utils.ts (1)
30-43
:getErrInstance
logic with switch statement.
The default clause already coversErrorType.HANDLEDEXCEPTION
; you can remove the redundantcase ErrorType.HANDLEDEXCEPTION
clause to simplify.switch (errorType) { case ErrorType.UNHANDLEDEXCEPTION: { ... } case ErrorType.UNHANDLEDREJECTION: { ... } - case ErrorType.HANDLEDEXCEPTION: default: return err; }
🧰 Tools
🪛 Biome (1.9.4)
[error] 39-39: Useless case clause.
because the default clause is present:
Unsafe fix: Remove the useless case.
(lint/complexity/noUselessSwitchCase)
packages/analytics-js/src/constants/logMessages.ts (1)
36-46
: Enhance error message clarity while maintaining good practicesThe new error constants follow good practices:
- Consistent use of context and LOG_CONTEXT_SEPARATOR
- Type-safe handling of nullable error string
- Clear naming conventions
However, consider making the messages more descriptive:
- `${context}${LOG_CONTEXT_SEPARATOR}Ignoring a non-error: ${errStr}.`; + `${context}${LOG_CONTEXT_SEPARATOR}Received non-error type in error handler: ${errStr}. This will be ignored.`; - `${context}${LOG_CONTEXT_SEPARATOR}Failed to log breadcrumb.`; + `${context}${LOG_CONTEXT_SEPARATOR}Failed to log error breadcrumb for debugging purposes.`; - `${context}${LOG_CONTEXT_SEPARATOR}Failed to handle the error.`; + `${context}${LOG_CONTEXT_SEPARATOR}Error handler encountered an unexpected failure while processing the error.`;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
packages/analytics-js/project.json
is excluded by!**/*.json
📒 Files selected for processing (23)
packages/analytics-js-common/src/types/ApplicationState.ts
(0 hunks)packages/analytics-js-common/src/utilities/checks.ts
(1 hunks)packages/analytics-js-common/src/utilities/errors.ts
(2 hunks)packages/analytics-js-plugins/__tests__/bugsnag/index.test.ts
(0 hunks)packages/analytics-js-plugins/__tests__/bugsnag/utils.test.ts
(0 hunks)packages/analytics-js-plugins/__tests__/errorReporting/index.test.ts
(0 hunks)packages/analytics-js/__tests__/components/capabilitiesManager/detection/adBlockers.test.ts
(5 hunks)packages/analytics-js/__tests__/components/configManager/ConfigManager.test.ts
(1 hunks)packages/analytics-js/__tests__/components/eventManager/EventManager.test.ts
(1 hunks)packages/analytics-js/__tests__/components/eventRepository/EventRepository.test.ts
(12 hunks)packages/analytics-js/__tests__/components/pluginsManager/PluginsManager.test.ts
(1 hunks)packages/analytics-js/__tests__/components/userSessionManager/UserSessionManager.test.ts
(1 hunks)packages/analytics-js/__tests__/services/ErrorHandler/ErrorHandler.test.ts
(1 hunks)packages/analytics-js/__tests__/services/ErrorHandler/processError.test.ts
(0 hunks)packages/analytics-js/__tests__/services/ErrorHandler/utils.test.ts
(6 hunks)packages/analytics-js/__tests__/services/HttpClient/HttpClient.test.ts
(2 hunks)packages/analytics-js/src/constants/logMessages.ts
(4 hunks)packages/analytics-js/src/services/ErrorHandler/ErrorHandler.ts
(2 hunks)packages/analytics-js/src/services/ErrorHandler/constant.ts
(0 hunks)packages/analytics-js/src/services/ErrorHandler/constants.ts
(1 hunks)packages/analytics-js/src/services/ErrorHandler/event/event.ts
(1 hunks)packages/analytics-js/src/services/ErrorHandler/utils.ts
(1 hunks)packages/analytics-js/src/state/slices/reporting.ts
(0 hunks)
💤 Files with no reviewable changes (7)
- packages/analytics-js/src/state/slices/reporting.ts
- packages/analytics-js/src/services/ErrorHandler/constant.ts
- packages/analytics-js-common/src/types/ApplicationState.ts
- packages/analytics-js/tests/services/ErrorHandler/processError.test.ts
- packages/analytics-js-plugins/tests/errorReporting/index.test.ts
- packages/analytics-js-plugins/tests/bugsnag/index.test.ts
- packages/analytics-js-plugins/tests/bugsnag/utils.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/analytics-js/src/services/ErrorHandler/constants.ts
- packages/analytics-js/src/services/ErrorHandler/event/event.ts
🧰 Additional context used
📓 Learnings (3)
packages/analytics-js/__tests__/components/userSessionManager/UserSessionManager.test.ts (1)
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1867
File: packages/analytics-js/__tests__/components/userSessionManager/UserSessionManager.test.ts:1692-1692
Timestamp: 2024-11-12T15:14:33.334Z
Learning: When updating test suites, changes to the domain (e.g., from 'example.com' to 'dummy.dataplane.host.com') are only necessary for tests that actually make network requests.
packages/analytics-js/src/constants/logMessages.ts (2)
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1823
File: packages/analytics-js-common/src/types/LoadOptions.ts:175-192
Timestamp: 2024-11-12T15:14:23.319Z
Learning: In this project, deprecated properties may still be used internally to provide backward compatibility for users, as the same types are used for both public-facing APIs and the internal codebase.
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1823
File: packages/analytics-js-common/src/types/LoadOptions.ts:0-0
Timestamp: 2024-11-12T15:14:23.319Z
Learning: In the `packages/analytics-js-common/src/types/LoadOptions.ts` file, the `dataplanes` property within the `SourceConfigResponse` type has been removed as it is no longer necessary.
packages/analytics-js/src/services/ErrorHandler/ErrorHandler.ts (1)
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1907
File: packages/analytics-js/src/services/ErrorHandler/ErrorHandler.ts:172-174
Timestamp: 2024-11-12T15:14:23.319Z
Learning: The function `onError` in `packages/analytics-js/src/services/ErrorHandler/ErrorHandler.ts` is acceptable as currently implemented, and refactoring suggestions are not required unless necessary.
🪛 Biome (1.9.4)
packages/analytics-js-common/src/utilities/errors.ts
[error] 50-50: Useless case clause.
because the default clause is present:
Unsafe fix: Remove the useless case.
(lint/complexity/noUselessSwitchCase)
packages/analytics-js/src/services/ErrorHandler/utils.ts
[error] 39-39: Useless case clause.
because the default clause is present:
Unsafe fix: Remove the useless case.
(lint/complexity/noUselessSwitchCase)
🔇 Additional comments (72)
packages/analytics-js/__tests__/components/userSessionManager/UserSessionManager.test.ts (1)
87-88
: Consider verifying error-handling coverage.By initializing
defaultHttpClient
withdefaultErrorHandler
, you have laid the groundwork for better error reporting. Please ensure you add or update test cases to validate that errors raised within the HTTP interactions ordefaultErrorHandler
are indeed captured and handled properly.Would you like me to help generate additional tests to ensure comprehensive coverage of error scenarios?
packages/analytics-js/__tests__/components/capabilitiesManager/detection/adBlockers.test.ts (2)
2-2
: Validate error handler usage.Importing
defaultErrorHandler
is a logical approach to ensure that thedetectAdBlockers
function leverages the updated error handling mechanism. However, confirm that all other test contexts or modules referencing a previous default error handler have also been updated to maintain consistency across the codebase.
41-41
: Confirm consistent parameter passing.Passing
defaultErrorHandler
todetectAdBlockers
aligns with the revised function signature. Ensure all other calls to this function across the codebase also include the error handler parameter, preventing potential mismatches.Also applies to: 57-57, 73-73
packages/analytics-js/__tests__/components/configManager/ConfigManager.test.ts (1)
154-154
: Good addition for clarity and completeness.By including
name
inexpectedSourceState
, the test now validates that source configuration also retains the source’s display name. This aligns well with the rest of the properties (id, config, workspaceId) and provides a more comprehensive verification of the actual source state.packages/analytics-js-common/src/utilities/errors.ts (3)
4-4
: Rebranded constant looks correct
Changing the identifier to[SDK DISPATCHED ERROR]
helps clarify internally dispatched errors.
6-16
: Helper function for extracting stack trace
The approach to checkstack
,stacktrace
, andopera#sourceloc
is comprehensive. The fallback toundefined
if the string is merely the error name and message helps avoid redundant stack info.
62-62
: Export list
Exporting the newgetStacktrace
function alongside existing exports looks consistent with the updated design.packages/analytics-js/__tests__/services/HttpClient/HttpClient.test.ts (2)
41-42
: Deferred error handler initialization
InstantiatingHttpClient
with only the logger, then callinginit
for the error handler, increases flexibility and modularity.
92-93
: “Fire and forget” behavior
Verifying thatgetAsyncData
returnsundefined
confirms asynchronous, no-result invocation. This test effectively covers the “no return” contract.packages/analytics-js/__tests__/services/ErrorHandler/ErrorHandler.test.ts (11)
1-2
: Mock imports
Using mockedHttpClient
andLogger
from__mocks__
directories isolates tests and ensures minimal coupling to real implementations.
11-11
: Constructor usage
PassingdefaultHttpClient
anddefaultLogger
to theErrorHandler
aligns with the refactored approach of removing any plugin dependency from the constructor.
14-46
: Breadcrumb storage and retrieval
Leaving and appending multiple breadcrumbs ensures coverage of the core logging mechanism. The approach in these tests thoroughly verifies that breadcrumb messages persist instate.reporting.breadcrumbs
.
48-63
: Error path testing
This test intentionally forces a null breadcrumb store to validate error handling. It is a solid approach for ensuring robustness when unexpected conditions occur.
66-75
: Ignoring non-error objects
Skipping invalid error inputs avoids spamming logs with meaningless data. The consistent logging of a warning confirms correct fallback behavior.
77-83
: Skipping external errors
Excluding errors lacking an SDK signature helps reduce noise and ensures logs remain relevant to the SDK’s scope.
85-93
: NPM installation path
Conditionally logging errors when the<app.installType>
is'npm'
is consistent with the updated design. This test ensures the code properly differentiates environment contexts.
95-105
: Silencing unhandled exceptions
Hiding unhandled exceptions from the console is sensible when the SDK needs more context to process them or has a dedicated strategy for background error handling.
108-119
: Explicitly dispatched errors
Adding[SDK DISPATCHED ERROR]
to the stack clarifies the error’s origin, enabling conditional logging for internal issues.
121-125
: Disable error reporting
Ensuring no external calls occur whenisErrorReportingEnabled
is false helps avoid undesired data transmissions and respects user settings.
128-133
: Filtering unreportable error messages
Skipping known messages like"The request failed"
helps minimize noise and prevents repeated or spurious notifications.packages/analytics-js/__tests__/components/eventRepository/EventRepository.test.ts (13)
9-9
: Import usage looks consistent and appropriate.
The new import fordefaultHttpClient
is consistent with the refactored constructor inEventRepository
. No issues noted.
94-98
: Constructor call aligns well with the updated signature.
PassingdefaultHttpClient
is consistent with the newEventRepository
constructor requirements.
135-139
: Consistent constructor usage.
Ensure that all unit tests now correctly provide the third argument for HTTP client.
149-153
: No issues found with this constructor invocation.
It is consistent with the recently updatedEventRepository
parameters.
180-184
: Constructor call validated.
Looks good for testing data-plane events queue logic.
196-200
: No concerns with the constructor invocation.
Consistently follows the new constructor signature forEventRepository
.
219-223
: Constructor call is consistent.
ProvidingmockPluginsManager
,defaultStoreManager
, anddefaultHttpClient
is aligned with the new logic.
241-245
: Constructor usage aligns with new parameters.
Single-responsibility approach for event queuing remains intact.
278-282
: Well-formed constructor call.
Matches the updatedEventRepository
argument list.
304-304
: Added argument for error handler is properly placed.
Ensures custom error handling in the test scenario.
324-328
: Constructor usage looks good.
No issues observed with providingdefaultHttpClient
.
347-351
: Consistent usage.
Ensures proper initialization with the new signature forEventRepository
.
359-363
: Instance creation checked.
Adheres to the updated constructor forEventRepository
.packages/analytics-js/__tests__/services/ErrorHandler/utils.test.ts (6)
3-16
: Imports align with the refactored error handling utilities.
These imports correctly bring in new functionalities such asisSDKError
and maintain consistency with the reorganized file structure.
236-236
: New describe block forisSDKError
.
This approach of table-driven tests is clear and comprehensive.
266-266
: Inline assertion effectively tests the logic.
The use ofisSDKError(event)
with domain variations is well-structured.
583-584
: Version and installation type references.
Valid placeholders ensure flexibility for environment-based values.
593-594
: Test case verifies positive condition forisAllowedToBeNotified
.
Clear usage, ensuring that typical errors are allowed.
598-601
: Test case validates filtering mechanism.
Ensures that specific error messages are not reported.packages/analytics-js/src/services/ErrorHandler/ErrorHandler.ts (20)
1-1
: Imports are coherently structured for the new error handling approach.
IncorporatingIHttpClient
and using constants from'../../constants/logMessages'
is consistent with the new design.
13-15
: Utility imports for error tracing.
These functions (getStacktrace
,MANUAL_ERROR_IDENTIFIER
) are key to identifying SDK-originated errors.
16-19
: Updated constants usage.
Adopting specialized error messages (e.g.,FAILED_ATTACH_LISTENERS_ERROR
,HANDLE_ERROR_FAILURE
) refines clarity.
23-30
: Utility imports fromutils
.
Bringing in multiple new utility functions centralizes error creation, metadata coverage, and filtering logic.
31-31
: ImportingdefaultHttpClient
fosters consistency.
Ensures a unified HTTP approach across the analytics services.
32-32
: Enhanced documentation fosters clarity.
The docstring succinctly captures the class purpose as an error service.
38-38
: Property introduction retains clarity.
NewhttpClient
property is well-named and typed, aligning withIErrorHandler
needs.
42-43
: Constructor signature change.
ReceivinghttpClient
first, then the optionally injectedlogger
, is consistent with the new refactored approach.
51-51
: Window error event usage.
Coverserror
events comprehensively. Ensure you handle custom error events in the future if needed.
57-57
: Unhandled rejection listener.
Captures promise rejections—good practice for modern JavaScript apps.
61-61
: Conditional fallback in non-browser environments.
Logging an error ifaddEventListener
is missing is a robust fallback.
71-74
: Early exit for undefined normalization.
Prevents further processing on unrecognized or unparseable errors.
78-79
: Prefix for error context.
Combining context and custom messages ensures consistent log labeling.
81-83
: SDK dispatch detection.
Leverages stacktrace scanning for theMANUAL_ERROR_IDENTIFIER
—a neat approach to differentiate SDK errors.
84-91
: Conditional check for non-SDK errors.
Skipping reporting for external errors in certain install types is logical.
94-94
: Ensuring error reporting is enabled before sending.
Excellent guard to avoid unnecessary HTTP calls.
116-124
: Logging handled or SDK-triggered errors.
Allows console visibility while avoiding double-reporting.
125-126
: Catch block ensures fallback logging.
Safely prevents infinite error loops on error handling.
137-143
: Breadcrumb handling.
Adding the newly created breadcrumb to state is straightforward. This design fosters better post-mortem diagnostics.
148-148
: Default error handler.
Centralizing the default instance is standard for global usage.packages/analytics-js/src/services/ErrorHandler/utils.ts (11)
1-29
: Initial imports and constants usage.
These references lay the groundwork for the new error processing logic (e.g.,ErrorType
,SDKError
, etc.).
45-50
: Streamlined breadcrumb creation.
Removing optional metadata simplifies usage and ensures a consistent structure.
52-55
:getReleaseStage
logic.
Development host detection is limited toDEV_HOSTS
. Keep it updated for new dev environments if needed.
57-60
:getAppStateForMetadata
:
Smart approach usingstringifyWithoutCircular
to avoid potential cycles and large objects.
62-65
:getURLWithoutQueryString
:
Cleanly strips query parameters—ideal for preserving user privacy.
67-71
:getBugsnagErrorEvent
signature.
Renaming ensures clarity: you now passexception
instead of the older error format.
72-120
: Constructing the Bugsnag event.
Captures environment data fromstate
thoroughly. Great usage ofclone
to avoid mutating the exception object.
122-129
:isAllowedToBeNotified
:
Filters known noisy or irrelevant errors. Minimal overhead withsome()
usage.
130-154
:isSDKError
:
Inspects file paths for known SDK prefixes, covering typical bundling scenarios. This is a robust heuristic.
156-169
:getErrorDeliveryPayload
:
Generates final JSON for metrics ingestion. Writing key, version, etc., are included for accurate tracing.
171-181
: Exports are coherent.
The new utility functions unify the approach to error instance creation, serialization, and filtering.packages/analytics-js/src/constants/logMessages.ts (2)
11-11
: LGTM: Import statement is correctly placedThe Nullable type import is appropriately added and used in the new NON_ERROR_WARNING constant.
Line range hint
277-328
: LGTM: Exports are properly updatedThe export list is correctly maintained with:
- All new error constants added
- Proper alphabetical ordering
- Removal of plugin-specific error constants aligning with the move to core module
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
packages/analytics-js/__tests__/services/ErrorHandler/utils.test.ts (1)
42-48
: **Potential Edge Cases forgetURLWithoutQueryString
**You might consider testing additional edge cases where
location.href
is empty or lacks a query param to ensure the function behaves as expected in those scenarios.packages/analytics-js/src/services/ErrorHandler/ErrorHandler.ts (1)
78-83
: **Selective Reporting for Non-SDK Errors **While skipping non-SDK errors is valid, consider logging or monitoring the volume of filtered errors for better insight into user issues.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
packages/analytics-js/package.json
is excluded by!**/*.json
packages/analytics-js/project.json
is excluded by!**/*.json
📒 Files selected for processing (5)
jest/jest.setup-dom.js
(1 hunks)packages/analytics-js/__tests__/services/ErrorHandler/ErrorHandler.test.ts
(1 hunks)packages/analytics-js/__tests__/services/ErrorHandler/utils.test.ts
(1 hunks)packages/analytics-js/src/constants/logMessages.ts
(4 hunks)packages/analytics-js/src/services/ErrorHandler/ErrorHandler.ts
(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/analytics-js/src/constants/logMessages.ts
🧰 Additional context used
📓 Learnings (1)
packages/analytics-js/src/services/ErrorHandler/ErrorHandler.ts (1)
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1907
File: packages/analytics-js/src/services/ErrorHandler/ErrorHandler.ts:172-174
Timestamp: 2024-11-12T15:14:23.319Z
Learning: The function `onError` in `packages/analytics-js/src/services/ErrorHandler/ErrorHandler.ts` is acceptable as currently implemented, and refactoring suggestions are not required unless necessary.
🔇 Additional comments (22)
packages/analytics-js/__tests__/services/ErrorHandler/utils.test.ts (9)
1-21
: **Well-Structured Initial Setup **The ESLint directives and mock configuration are straightforward, and the imports (including type imports) neatly prepare the test environment.
23-40
: **Comprehensive Test forcreateNewBreadcrumb
**The test verifies all fields, including
metaData
,type
, and timestamps. This fosters confidence in breadcrumb creation.
50-83
: **Extensive Hostname Testing ingetReleaseStage
**This test suite covers localhost scenarios and other hostnames comprehensively. Good job ensuring that appropriate release stages are returned for each environment.
85-118
: **Robust Pattern Matching inisSDKError
**The varied file paths and conditions thoroughly confirm which errors originate from the SDK. This precise coverage helps avoid false positives.
120-264
: **In-Depth Validation ofgetAppStateForMetadata
**This section rigorously tests nested signals, arrays, and objects, ensuring correct JSON transformations. The usage of
APP_STATE_EXCLUDE_KEYS
is well-verified.
266-575
: **Detailed Testing forgetBugsnagErrorEvent
**The test scenario captures comprehensive property checks, including
app
,device
, andmetaData
fields. It ensures the error event payload matches expected structure and data.
577-595
: **Concise Check ingetErrorDeliveryPayload
**Your approach to verifying output structure with
expect.any(String)
ensures the payload is properly serialized. This test helps maintain consistent reporting behavior.
597-609
: **Clear Criteria inisAllowedToBeNotified
**The test verifies the filtering logic for allowed error messages, ensuring undesired errors are excluded from reporting.
611-643
: **Comprehensive Coverage forgetErrInstance
**All scenarios—handled, unhandled, and promise rejections—are tested. This strongly validates error extraction logic.
jest/jest.setup-dom.js (1)
13-27
: **Minimal Mock forPromiseRejectionEvent
**Conditionally attaching the mock class to the global scope ensures consistent behavior in test environments that lack
PromiseRejectionEvent
. Neat solution!packages/analytics-js/src/services/ErrorHandler/ErrorHandler.ts (7)
34-39
: **Dependency Injection ofhttpClient
**Replacing
pluginEngine
withhttpClient
simplifies error reporting logic and clarifies responsibilities. Great step toward more modular design.
45-54
: **Global Error Listeners **Attaching event listeners for both
error
andunhandledrejection
ensures robust coverage of runtime exceptions.
63-66
: **Pre-check fornormalizedError
**Early return if the error is undefined avoids unnecessary logic and possible null references.
93-105
: **External Error Reporting viahttpClient
**Sending error data as raw JSON is a clean, straightforward approach. This ensures no additional formatting overhead on the server side.
108-118
: **Graceful Failure Handling inonError
**Catching and logging errors from within
onError
helps prevent error loops. This is an excellent defensive measure.
129-134
: **Breadcrumb Collection **Storing breadcrumbs in
state.reporting.breadcrumbs
is simple yet effective. It preserves user context leading up to errors without extra overhead.
140-140
: **Default Export Initialization **
defaultErrorHandler
withdefaultHttpClient
anddefaultLogger
is consistent with the revised constructor design.packages/analytics-js/__tests__/services/ErrorHandler/ErrorHandler.test.ts (5)
1-4
: **Updated Mocks Import **Pulling in
defaultHttpClient
anddefaultLogger
from the mocks folder enhances test isolation.
12-12
: **Correct Instantiation ofErrorHandler
**Using
(defaultHttpClient, defaultLogger)
aligns with the new constructor signature, removing reliance on the oldpluginEngine
.
15-47
: **Coverage for Global Error Handlers **Testing unhandled error and promise rejection events ensures that core listener functionality is triggered accurately.
48-97
: **Breadcrumb Logging **Verifying breadcrumb appending and error handling is thorough. The scenario where
state.reporting.breadcrumbs.value
is null ensures resilience.
100-210
: **RefinedonError
Tests **The suite addresses diverse error conditions and toggles for error reporting. This comprehensive approach validates the entire error-handling workflow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/analytics-js/src/components/core/Analytics.ts (1)
254-256
: Consider reordering parameters for consistency.While the initialization is correct, consider reordering the parameters to maintain consistency with other service initializations in the file where core services (errorHandler, logger) typically come first:
- this.eventRepository = new EventRepository( - this.pluginsManager, - this.storeManager, - this.httpClient, - this.errorHandler, - this.logger, - ); + this.eventRepository = new EventRepository( + this.errorHandler, + this.logger, + this.pluginsManager, + this.storeManager, + this.httpClient, + );
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
packages/analytics-js/__tests__/components/capabilitiesManager/CapabilitiesManager.test.ts
(3 hunks)packages/analytics-js/__tests__/components/capabilitiesManager/detection/adBlockers.test.ts
(3 hunks)packages/analytics-js/src/components/capabilitiesManager/CapabilitiesManager.ts
(3 hunks)packages/analytics-js/src/components/capabilitiesManager/detection/adBlockers.ts
(1 hunks)packages/analytics-js/src/components/capabilitiesManager/types.ts
(1 hunks)packages/analytics-js/src/components/core/Analytics.ts
(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/analytics-js/tests/components/capabilitiesManager/detection/adBlockers.test.ts
🔇 Additional comments (13)
packages/analytics-js/__tests__/components/capabilitiesManager/CapabilitiesManager.test.ts (3)
2-2
: Validate import of defaultHttpClient
Bringing indefaultHttpClient
aligns with the new constructor requirements forCapabilitiesManager
.
43-47
: Successfully passing the required parameters
Instantiating theCapabilitiesManager
withdefaultHttpClient
,defaultErrorHandler
, andmockLogger
is consistent with the updated constructor signature.
106-109
: Omitting logger confirms fallback behavior
This test scenario properly verifies that no warnings are logged when the logger parameter is absent, adhering to the class's optional logger design.packages/analytics-js/src/components/capabilitiesManager/types.ts (2)
4-4
: Added import for IHttpClient
This import ensures theICapabilitiesManager
interface can declare a strict HTTP client dependency.
7-8
: New required properties
Making bothhttpClient
anderrorHandler
mandatory inICapabilitiesManager
enforces consistency and ensures that error handling and network operations can be reliably injected.packages/analytics-js/src/components/capabilitiesManager/detection/adBlockers.ts (2)
1-1
: HttpClient import introduced
ImportingIHttpClient
is required to pass it as a parameter, consolidating ad-blocker detection under a unified HTTP mechanism.
4-4
: Simplified function signature
Requiring a singlehttpClient
parameter streamlines external dependencies and avoids optional logging or error handling logic here. This clarifies responsibility for error handling and logging outside the function.packages/analytics-js/src/components/capabilitiesManager/CapabilitiesManager.ts (4)
15-15
: Imported IHttpClient
IntroducingIHttpClient
ensures that network operations are consistently handled across the capabilities management workflow.
40-41
: New required properties in class
DefininghttpClient
anderrorHandler
as mandatory class properties locks in consistent error and HTTP handling throughout this manager.
45-48
: Constructor now mandates httpClient and errorHandler
Requiring these parameters promotes explicit dependency injection, fostering better testability and clearer ownership of error and HTTP handling.
112-112
: Refined detectAdBlockers usage
Passingthis.httpClient
ensures the ad-blocker detection function can perform HEAD requests without relying on global or optional injections.packages/analytics-js/src/components/core/Analytics.ts (2)
101-106
: LGTM! Proper initialization sequence and dependency injection.The initialization sequence is well-structured with proper dependency injection. The
httpClient
is correctly initialized with theerrorHandler
before being passed to thecapabilitiesManager
.
101-106
: Verify consistent error handling initialization patterns.Let's verify that the error handling initialization pattern is consistent across the codebase.
Also applies to: 254-256
✅ Verification successful
Let me try a different pattern to search for error handling initialization.
Based on the search results, I can now provide a comprehensive analysis of the error handling initialization patterns:
Error handling initialization is consistent across the codebase
The error handling initialization follows a consistent pattern throughout the codebase:
- The
ErrorHandler
is properly initialized in the Analytics core class and passed down to all dependent components- The
httpClient.init()
is correctly called with the error handler instance- All major components (ConfigManager, CapabilitiesManager, EventManager, etc.) consistently receive the error handler through their constructors
- Components uniformly implement error handling by:
- Having an
errorHandler
property- Accepting it in their constructor
- Using it in their
onError
methodsThe changes in lines 101-106 maintain this consistent pattern by:
- Initializing the HTTP client with the error handler
- Passing the error handler to the CapabilitiesManager constructor
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for error handler initialization patterns in the codebase echo "Searching for error handler initialization patterns..." ast-grep --pattern 'new $class($_, $errorHandler, $_)' echo "Searching for httpClient initialization patterns..." ast-grep --pattern '$httpClient.init($errorHandler)'Length of output: 343
Script:
#!/bin/bash # Search for error handler patterns with more context echo "Searching for error handler initialization patterns..." rg -n "errorHandler" -A 2 -B 2 echo "\nSearching for httpClient initialization patterns..." rg -n "httpClient.init" -A 2 -B 2Length of output: 70508
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #1984 +/- ##
===========================================
- Coverage 61.27% 61.25% -0.02%
===========================================
Files 484 478 -6
Lines 16616 16386 -230
Branches 3340 3228 -112
===========================================
- Hits 10182 10038 -144
+ Misses 5213 5161 -52
+ Partials 1221 1187 -34 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (5)
packages/analytics-js/__tests__/browser.test.ts (5)
1-4
: Consider removing global rule disabling if possible
Disablingeslint
rules at the file level might hide issues beyond the intended scope. If these directives are not strictly necessary, consider removing or narrowing them to specific lines, improving overall code quality.
49-66
: Use async/await to avoid callback-based tests
The current test relies on adone
callback to handle asynchronous flow. Converting to async/await can simplify the code, improve readability, and reduce the likelihood of callback-related errors.-it('should process the buffered API calls when SDK script is loaded', done => { +it('should process the buffered API calls when SDK script is loaded', async () => { // Mock XHR window.XMLHttpRequest = jest.fn(() => xhrMock) as unknown as typeof XMLHttpRequest; loadingSnippet(); window.rudderanalytics?.page(); - window.rudderanalytics?.ready(() => { - expect((window.rudderanalytics as any).push).not.toBe(Array.prototype.push); - expect(xhrMock.send).toHaveBeenCalledTimes(2); - done(); - }); + await new Promise(resolve => { + window.rudderanalytics?.ready(() => resolve(true)); + }); + + expect((window.rudderanalytics as any).push).not.toBe(Array.prototype.push); + expect(xhrMock.send).toHaveBeenCalledTimes(2); require(pathToSdk); });
69-80
: Maintain consistent use of async/await in beforeEach
Similar to the previous suggestion, using async/await inbeforeEach
can improve the clarity of test setup and prevent potential race conditions if future tests become more complex.
83-91
: Expand test assertions
You're currently validating that the expected number of requests is sent. Consider also verifying the correctness of payloads or request method attributes, especially if request structure is critical in production.
94-110
: UUID generation test coverage
The test effectively checks for a UUID v4 pattern. If collisions or invalid generation are concerns, you may add coverage for scenarios like re-initializing the SDK multiple times under varied conditions.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/analytics-js/__tests__/browser.test.ts
(2 hunks)packages/analytics-js/__tests__/nativeSdkLoader.js
(2 hunks)
🧰 Additional context used
📓 Learnings (1)
packages/analytics-js/__tests__/nativeSdkLoader.js (1)
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1708
File: packages/analytics-js/__tests__/nativeSdkLoader.js:31-33
Timestamp: 2024-11-12T15:14:23.319Z
Learning: The loading snippet in `packages/analytics-js/__tests__/nativeSdkLoader.js` is a standard part of the SDK, and no changes are desired on it.
🔇 Additional comments (4)
packages/analytics-js/__tests__/nativeSdkLoader.js (1)
59-59
: Good use of nullish coalescing to safeguardloadOptions
.
The introduction ofloadOptions
and usingloadOptions ?? {}
ensures the snippet passes valid arguments to theload
method even when none are provided. This change adds flexibility without breaking existing functionality. Also, based on the retrieved learnings, no further modifications are needed here to preserve the snippet’s standard usage.packages/analytics-js/__tests__/browser.test.ts (3)
5-5
: Check distribution script reference
Switching torsa.js
instead ofrsa.min.js
may slow down test execution and potentially mask differences between minified and non-minified builds. Ensure both files are tested if your deployment depends on the minified version.
112-133
: Comprehensive user reset test
This test thoroughly covers clearing user identity and traits. Nice work ensuring that the anonymous ID remains intact. No changes needed.
135-155
: Thorough coverage of reset(true) functionality
This test ensures that an entirely new anonymous ID is generated after a full reset, providing confidence that user session data is rebuilt correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (11)
packages/analytics-js/__tests__/nativeSdkLoader.js (1)
4-4
: Consider making the SDK version dynamic.The SDK version (3.0.10) is hardcoded in the snippet. This could become outdated and might need frequent updates.
Consider reading this value from package.json or environment variables to ensure it stays in sync with the actual SDK version.
packages/analytics-js/__tests__/browser.test.ts (5)
9-30
: Consider extracting mock configuration to a separate test utilities file.The mock source configuration contains multiple test constants that could be reused across different test files. Consider moving this to a shared test utilities file to improve maintainability and reusability.
67-76
: Enhance test cleanup.Consider clearing the mock's call history in the cleanup to ensure complete isolation between tests:
afterEach(() => { jest.resetModules(); + jest.clearAllMocks(); window.rudderanalytics = undefined; window.XMLHttpRequest = originalXMLHttpRequest; });
77-94
: Enhance preload buffer test coverage.The test verifies the number of XHR calls but could be more thorough:
- Verify the content of each XHR call
- Add error cases (e.g., failed source configuration request)
Example enhancement:
it('should process the buffered API calls when SDK script is loaded', async () => { window.XMLHttpRequest = jest.fn(() => xhrMock) as unknown as typeof XMLHttpRequest; loadingSnippet(WRITE_KEY, DATA_PLANE_URL); const pageEvent = { name: 'test-page' }; const trackEvent = { event: 'test-event' }; window.rudderanalytics?.page(pageEvent); window.rudderanalytics?.track(trackEvent.event); await loadAndWaitForSDK(); expect((window.rudderanalytics as any).push).not.toBe(Array.prototype.push); expect(xhrMock.send).toHaveBeenCalledTimes(3); // Verify content of each call expect(JSON.parse(xhrMock.send.mock.calls[1][0])).toMatchObject({ type: 'page', ...pageEvent, }); expect(JSON.parse(xhrMock.send.mock.calls[2][0])).toMatchObject({ type: 'track', ...trackEvent, }); });
123-139
: Enhance getAnonymousId test coverage.Consider adding these test cases:
- Test with invalid stored anonymous ID
- Test with maximum length anonymous ID
- Test persistence across page reloads
Example additional test:
it('should handle invalid stored anonymous ID', () => { // Simulate corrupted storage localStorage.setItem('rl_anonymous_id', 'invalid-uuid'); const anonId = window.rudderanalytics?.getAnonymousId(); // Should generate new valid UUID expect(anonId).toMatch(/^[\da-f]{8}-[\da-f]{4}-4[\da-f]{3}-[\da-f]{4}-[\da-f]{12}$/i); });
112-120
: Add performance verification for batch API calls.The test verifies individual API calls but should also verify performance with batch operations:
Example enhancement:
it('should handle multiple API calls efficiently', () => { const startTime = performance.now(); // Make multiple API calls in quick succession for (let i = 0; i < 100; i++) { window.rudderanalytics?.track(`test-event-${i}`); } const endTime = performance.now(); const executionTime = endTime - startTime; // Verify execution time is within acceptable range expect(executionTime).toBeLessThan(1000); // 1 second // Verify all requests were made expect(xhrMock.send).toHaveBeenCalledTimes(101); // 100 events + 1 source config });packages/analytics-js-common/__tests__/utilities/errors.test.ts (5)
25-35
: Decoratingstacktrace
and performance considerations regardingdelete
.
Usingdelete error.stack
effectively simulates different error properties. However, static analysis suggests avoiding thedelete
operator for performance reasons. You may consider assigningundefined
instead if you want to remove the property:- delete error.stack; + error.stack = undefined;🧰 Tools
🪛 Biome (1.9.4)
[error] 29-29: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
37-47
: Opera sourceloc test & performance hint.
Similar to the above, you can remove the property by settingerror.stack = undefined
instead of usingdelete
. This keeps the code consistent and aligns with performance best practices.🧰 Tools
🪛 Biome (1.9.4)
[error] 41-41: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
56-64
: Stacktrace property check & performance hint.
You've tested fallback to theerror.stacktrace
property. Likewise, consider replacing thedelete error.stack
usage for performance reasons as suggested earlier.🧰 Tools
🪛 Biome (1.9.4)
[error] 60-60: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
66-74
: Opera sourceloc property check & performance hint.
Once again, consider settingerror.stack = undefined
rather thandelete error.stack
to align with best practices regarding object property removal.🧰 Tools
🪛 Biome (1.9.4)
[error] 70-70: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
76-81
: Undefined scenario test.
This test ensures thatgetStacktrace
gracefully handles situations with no valid stack. The same suggestion applies about usingerror.stack = undefined
instead ofdelete error.stack
.🧰 Tools
🪛 Biome (1.9.4)
[error] 78-78: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
packages/analytics-js-common/__tests__/utilities/errors.test.ts
(1 hunks)packages/analytics-js-plugins/.size-limit.mjs
(1 hunks)packages/analytics-js/.size-limit.mjs
(1 hunks)packages/analytics-js/__tests__/browser.test.ts
(1 hunks)packages/analytics-js/__tests__/nativeSdkLoader.js
(2 hunks)packages/analytics-v1.1/.size-limit.js
(1 hunks)
🧰 Additional context used
📓 Learnings (1)
packages/analytics-js/__tests__/nativeSdkLoader.js (1)
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1708
File: packages/analytics-js/__tests__/nativeSdkLoader.js:31-33
Timestamp: 2024-11-12T15:14:23.319Z
Learning: The loading snippet in `packages/analytics-js/__tests__/nativeSdkLoader.js` is a standard part of the SDK, and no changes are desired on it.
🪛 Biome (1.9.4)
packages/analytics-js-common/__tests__/utilities/errors.test.ts
[error] 29-29: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
[error] 41-41: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
[error] 60-60: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
[error] 70-70: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
[error] 78-78: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
🔇 Additional comments (19)
packages/analytics-js-plugins/.size-limit.mjs (2)
16-20
: Confirm compliance with size limit update policy.You’ve updated the size limit to '14 KiB' for the Legacy plugins bundle. According to the file header, any changes to the size limits require approval from the code owners. Please ensure you have their consent, as these modifications might affect the release process.
24-24
: Validate the feasibility of reducing the size limit for Modern plugins bundle.You’ve reduced the size limit to '6 KiB'. Ensure the actual bundle size remains within this new threshold, especially if future merges introduce additional code. Consider adding a build step to confirm the final output size remains under 6 KiB.
packages/analytics-js/__tests__/nativeSdkLoader.js (2)
59-59
: Verify the impact of the new load method signature.The load method invocation has been modified to use the new parameters. This change:
- Makes the snippet more configurable but potentially less standardized
- Could affect existing implementations that expect the default behavior
Let's verify the standard load method signature across the codebase:
✅ Verification successful
The load method signature is consistent across the codebase
Based on the search results, the load method signature consistently follows the pattern:
rudderanalytics.load(writeKey, dataPlaneUrl, options)All examples and test files across different versions (v1, v1.1, v2, v3) use this same signature with three parameters:
- writeKey (required)
- dataPlaneUrl (required)
- options (optional configuration object)
The modification in the test file to use
loadOptions ?? {}
as the third parameter maintains backward compatibility by:
- Preserving the same parameter order
- Providing an empty object as fallback when loadOptions is null/undefined, which matches the existing behavior
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for load method signatures ast-grep --pattern 'rudderanalytics.load($$$)'Length of output: 10205
1-1
:⚠️ Potential issueReconsider modifying the standard loading snippet.
Based on previous feedback, modifications to this loading snippet are not desired as it's a standard part of the SDK. Consider reverting the function signature change to maintain consistency.
Let's verify if this snippet is used elsewhere in the codebase:
packages/analytics-v1.1/.size-limit.js (2)
43-43
: Confirm naming convention alignment with documentation.You changed the entry name to
'Core (v1.1) - Legacy - CDN'
. Ensure all references in your documentation or usage instructions reflect this updated naming convention so users can easily recognize the version.
48-48
: Approve naming update for Modern CDN build.Renaming to
'Core (v1.1) - Modern - CDN'
looks consistent with the versioned naming scheme. Great job maintaining clarity in build names.packages/analytics-js/.size-limit.mjs (6)
10-27
: Double-check updated limits for Core - Legacy entries.The adjusted limits for:
- ESM (line 10)
- CJS (line 16)
- UMD (line 22)
- CDN (line 27)
all appear consistent. Provide justification for lowering these limits and confirm with code owners, as the file’s header explicitly requests their review for size-limit changes.
33-50
: Ensure alignment with the newly increased size limits for Core - Modern.The changes at:
- ESM (line 33)
- CJS (line 39)
- UMD (line 45)
- CDN (line 50)
increase the allowed size. Please confirm no unintended payload bloat has slipped in. A larger allowance should be matched by a rationale in the PR description or a comment in the code.
56-68
: Validate the reduced size limits for Core (Bundled) - Legacy.Changes at:
- ESM (line 56)
- CJS (line 62)
- UMD (line 68)
reflect consistent decreases in the size-limits. Verify that removing or refactoring code (e.g., older plugin or error reporting logic) actually achieves these smaller footprints.
74-86
: Confirm stability of Core (Bundled) - Modern with new lower limits.At lines 74, 80, and 86, the limit is decreased to 39 KiB. Ensure performance improvements or plugin refactoring have enabled this limit reduction without losing functionality.
92-104
: Check the updated size constraints for Core (Content Script) - Legacy.Size limits are set to 48 KiB at lines 92, 98, and 104. Make sure all content-script functionalities remain intact after any plugin removals or error-handling consolidations.
110-122
: Assess reduced size boundary for Core (Content Script) - Modern.For lines 110, 116, and 122, the size limit is 39 KiB. If these deltas result from code migrations or plugin changes, confirm those changes are stable and tested across browsers.
packages/analytics-js-common/__tests__/utilities/errors.test.ts (7)
1-1
: Imports look good.
No issues found importingdispatchErrorEvent
andgetStacktrace
.
5-6
: Mock setup is clear.
You’ve succinctly introduceddispatchEventMock
and preserved the original dispatch event. This is a good practice when mocking global functionality.
8-10
: BeforeEach block.
ReplacingglobalThis.dispatchEvent
with your mock for each test ensures clean isolation across tests.
12-14
: AfterEach block.
RestoringglobalThis.dispatchEvent
preserves the global state for subsequent tests. No concerns here.
17-23
: Thorough test for dispatching error events.
Verifying thatdispatchErrorEvent
correctly appends[SDK DISPATCHED ERROR]
to the stack and dispatches anErrorEvent
demonstrates robust coverage of the new functionality.
50-54
: ValidatinggetStacktrace
with string stack.
This provides clear verification that the function returns the rawstack
property when present.
83-87
: Name and message equivalence check.
Great job verifying that a stack identical toname: message
yieldsundefined
. This covers a corner case in error stack handling.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (4)
packages/analytics-js-common/src/utilities/errors.ts (4)
6-16
: Consider additional edge case handlingWhile the implementation is solid, consider these defensive improvements:
- Guard against potential undefined error object
- Handle cases where properties exist but are empty strings
const getStacktrace = (err: any): string | undefined => { + if (!err) { + return undefined; + } const { stack, stacktrace } = err; const operaSourceloc = err['opera#sourceloc']; const stackString = stack ?? stacktrace ?? operaSourceloc; - if (!!stackString && typeof stackString === 'string') { + if (!!stackString && typeof stackString === 'string' && stackString.trim().length > 0) { return stackString; } return undefined; };
41-55
: Remove redundant case clauseThe case clause for
operaSourceloc
is redundant as it falls through to the default case.switch (errStack) { case stack: // eslint-disable-next-line no-param-reassign error.stack = `${stack}\n${MANUAL_ERROR_IDENTIFIER}`; break; case stacktrace: // eslint-disable-next-line no-param-reassign error.stacktrace = `${stacktrace}\n${MANUAL_ERROR_IDENTIFIER}`; break; - case operaSourceloc: default: // eslint-disable-next-line no-param-reassign error['opera#sourceloc'] = `${operaSourceloc}\n${MANUAL_ERROR_IDENTIFIER}`; break; }
🧰 Tools
🪛 Biome (1.9.4)
[error] 50-50: Useless case clause.
because the default clause is present:
Unsafe fix: Remove the useless case.
(lint/complexity/noUselessSwitchCase)
36-56
: Document side effects in function behaviorThe function modifies the error object directly. This side effect should be documented in the function's JSDoc.
Add JSDoc comment above the function:
/** * Dispatches an error event to the global scope. * @param error - The error to dispatch * @sideEffect Modifies the error's stack trace by appending an identifier */🧰 Tools
🪛 Biome (1.9.4)
[error] 50-50: Useless case clause.
because the default clause is present:
Unsafe fix: Remove the useless case.
(lint/complexity/noUselessSwitchCase)
59-61
: Improve type safety for global scope accessThe type assertion for
globalThis
could be more specific to ensure type safety.- (globalThis as typeof window).dispatchEvent( + (globalThis as Window & typeof globalThis).dispatchEvent(
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/analytics-js-common/src/utilities/errors.ts
(2 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
packages/analytics-js-common/src/utilities/errors.ts
[error] 50-50: Useless case clause.
because the default clause is present:
Unsafe fix: Remove the useless case.
(lint/complexity/noUselessSwitchCase)
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: Bundle size checks
- GitHub Check: Unit Tests and Lint
- GitHub Check: Security and code quality checks
🔇 Additional comments (1)
packages/analytics-js-common/src/utilities/errors.ts (1)
4-4
: LGTM! Improved error identifier namingThe new identifier '[SDK DISPATCHED ERROR]' better reflects its purpose and aligns with the migration of error reporting to the core module.
Docstrings generation was requested by @saikumarrs. * #1984 (comment) The following files were modified: * `packages/analytics-js/__tests__/nativeSdkLoader.js`
Note We have generated docstrings for this pull request, at #1998 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (22)
packages/analytics-js/__tests__/components/capabilitiesManager/CapabilitiesManager.test.ts (1)
120-135
: Consider enhancing adblocker detection test coverage.Good job on testing the HTTP client interaction! To make the test suite more robust, consider adding:
- Verification of the callback behavior
- A negative test case when
sendAdblockPage
is false- Error handling test cases
- A more descriptive test name that specifies what aspect is being verified
Here's a suggested additional test case:
it('should not initiate adblocker detection when disabled', () => { state.loadOptions.value.sendAdblockPage = false; state.lifecycle.sourceConfigUrl.value = 'https://www.dummy.url'; const getAsyncDataSpy = jest.spyOn(defaultHttpClient, 'getAsyncData'); capabilitiesManager.init(); expect(getAsyncDataSpy).not.toHaveBeenCalled(); });packages/analytics-js/__tests__/components/configManager/ConfigManager.test.ts (3)
182-190
: Consider adding more specific error scenarios.While the basic error case is covered, consider adding test cases for different types of failures (network errors, timeout, etc.) to ensure robust error handling.
+ it('should handle network errors when fetching source config', () => { + const networkError = new Error('Network failure'); + configManagerInstance.processConfig(undefined, networkError); + + expect(defaultErrorHandler.onError).toHaveBeenCalledWith( + networkError, + 'ConfigManager', + 'Network error while fetching source config', + ); + });
344-379
: Consider adding timeout test for getSourceConfig promise.While promise handling is well tested, consider adding a test case for promise timeout scenarios.
+ it('should handle timeout from getSourceConfig promise', done => { + jest.useFakeTimers(); + const timeoutPromise = new Promise(resolve => setTimeout(resolve, 10000)); + state.loadOptions.value.getSourceConfig = () => timeoutPromise; + + configManagerInstance.getConfig(); + jest.advanceTimersByTime(15000); + + setTimeout(() => { + expect(defaultLogger.error).toHaveBeenCalledWith( + 'ConfigManager:: Source config fetch timed out after 10s' + ); + jest.useRealTimers(); + done(); + }, 1); + });
11-14
: Consider adding type tests.Since the file imports types from the ConfigManager, consider adding type-level tests to ensure type safety.
// Add type tests it('should type check source config response', () => { const validResponse: SourceConfigResponse = dummySourceConfigResponse; // This should cause a TypeScript error // @ts-expect-error const invalidResponse: SourceConfigResponse = { invalid: 'data' }; });packages/analytics-js/__tests__/services/ErrorHandler/utils.test.ts (3)
21-23
: Consider using a dedicated test utilities file for mocksThe UUID mock could be moved to a shared test utilities file to maintain consistency across test files and improve maintainability.
-jest.mock('@rudderstack/analytics-js-common/utilities/uuId', () => ({ - generateUUID: jest.fn().mockReturnValue('test_uuid'), -}));Create a new file
__tests__/utils/mocks.ts
:export const mockUUID = 'test_uuid'; export const setupCommonMocks = () => { jest.mock('@rudderstack/analytics-js-common/utilities/uuId', () => ({ generateUUID: jest.fn().mockReturnValue(mockUUID), })); };
275-584
: Improve test maintainability in getBugsnagErrorEvent suiteThe test setup involves complex state initialization. Consider extracting the setup into helper functions and using more descriptive test case names.
const setupErrorTestState = () => { state.session.sessionInfo.value = { id: 123 }; state.context.app.value.installType = 'cdn'; state.autoTrack.pageLifecycle.visitId.value = 'test-visit-id'; state.context.library.value.snippetVersion = 'sample_snippet_version'; // ... other state setup }; const createTestException = () => ({ errorClass: 'Error', message: 'dummy message', type: 'browserjs', stacktrace: [/* ... */], }); describe('getBugsnagErrorEvent', () => { it('should return complete error event payload with all metadata when state is fully populated', () => { setupErrorTestState(); const exception = createTestException(); // ... rest of the test }); });
606-618
: Enhance test coverage for isAllowedToBeNotifiedThe test cases could be more comprehensive. Consider adding tests for edge cases and different error message patterns.
describe('isAllowedToBeNotified', () => { const testCases = [ ['dummy error', true, 'should allow generic errors'], ['The request failed', false, 'should not allow request failures'], ['', true, 'should allow empty messages'], [null, true, 'should handle null messages'], ['Network request failed', false, 'should not allow network errors'], ]; test.each(testCases)('%s -> %s (%s)', (message, expected, testName) => { const result = isAllowedToBeNotified({ message } as unknown as Exception); expect(result).toBe(expected); }); });packages/analytics-js/src/services/ErrorHandler/event/event.ts (5)
21-35
: Consider enhancing error handling in formatStackframe.While the function handles the basic edge cases, consider adding more robust error handling:
- Validate input frame properties
- Handle potential null/undefined values
- Add type guards for better type safety
const formatStackframe = (frame: FrameType): Stackframe => { + if (!frame) { + return { + file: GLOBAL_CODE, + method: GLOBAL_CODE, + lineNumber: -1, + columnNumber: -1, + }; + } + const f = { - file: frame.fileName, - method: normalizeFunctionName(frame.functionName), - lineNumber: frame.lineNumber, - columnNumber: frame.columnNumber, + file: frame.fileName ?? '', + method: frame.functionName ? normalizeFunctionName(frame.functionName) : '', + lineNumber: frame.lineNumber ?? -1, + columnNumber: frame.columnNumber ?? -1, };
37-37
: Consider moving ensureString to common utilities.The
ensureString
utility function could be useful across different modules. Consider moving it to@rudderstack/analytics-js-common/utilities/string
.
49-58
: Enhance error handling in the stacktrace reduction.The reduce operation's try-catch block silently swallows errors. Consider:
- Logging the error for debugging
- Using a more explicit filtering mechanism
stacktrace: stacktrace.reduce((accum: Stackframe[], frame: FrameType) => { const f = formatStackframe(frame); - // don't include a stackframe if none of its properties are defined try { - if (JSON.stringify(f) === '{}') return accum; - return accum.concat(f); + const hasValidProperties = Object.values(f).some(v => v !== undefined && v !== ''); + return hasValidProperties ? accum.concat(f) : accum; } catch (err) { + logger.debug(`Failed to process stack frame: ${err.message}`); return accum; } }, []),
75-82
: Add debug logging for stack trace parsing failures.The catch block silently handles parsing failures. Consider adding debug logging to help with troubleshooting.
try { const stacktrace = ErrorStackParser.parse(error); return createException(error.name, error.message, msgPrefix, stacktrace); - } catch { + } catch (err) { + logger.debug(`Failed to parse error stack trace: ${err.message}`); return createException(error.name, error.message, msgPrefix, []); }
1-91
: Well-structured implementation aligning with core module migration.The error handling implementation successfully achieves the PR's objective of moving error reporting to the core module. The code is well-organized, properly typed, and maintains a clear separation of concerns.
A few architectural considerations:
- The error handling is now more centralized and consistent
- The implementation properly handles various edge cases
- The code is well-positioned for future enhancements
This implementation will help achieve immediate error reporting without waiting for plugins to load, as mentioned in the PR objectives.
packages/analytics-js/__tests__/services/ErrorHandler/event.test.ts (5)
13-23
: Consider adding test cases for undefined/null inputsThe test cases are comprehensive for string inputs, but should also verify behavior with undefined/null inputs to ensure robust error handling.
const testCases: any[][] = [ ['functionName', 'functionName'], ['global code', 'global code'], ['GLOBAL CODE', 'global code'], ['Global Code', 'global code'], ['Global code', 'global code'], ['global Code', 'global code'], ['globalcode', 'globalcode'], ['global code with something extra', 'global code with something extra'], ['', ''], + [undefined, ''], + [null, ''], ];
48-91
: Enhance type safety and edge case coverageWhile the test cases cover the main scenarios, consider these improvements:
- Add explicit interface/type for stack frame instead of using any[][]
- Add test cases for non-numeric line/column numbers
interface StackFrame { fileName: string; functionName: string; lineNumber: number; columnNumber: number; } const testCases: [StackFrame, FormattedStackFrame][] = [ // existing cases... [ { fileName: 'file.js', functionName: 'func', lineNumber: 'invalid' as any, columnNumber: 'invalid' as any, }, { file: 'file.js', method: 'func', lineNumber: -1, columnNumber: -1, }, ], ];
98-154
: Well-structured tests with good edge case handling!The test effectively handles circular references and invalid frames. Consider adding a test case for empty stacktrace to complete the coverage.
it('should handle empty stacktrace', () => { expect(createException('ErrorClass', 'message', 'prefix', [])).toEqual({ errorClass: 'ErrorClass', message: 'prefixmessage', type: 'browserjs', stacktrace: [], }); });
156-183
: Add test case for Error subclassesThe tests cover the main scenarios well. Consider adding a test case for Error subclasses (e.g., TypeError, ReferenceError) to ensure proper handling of all error types.
it('should handle Error subclasses', () => { const typeError = new TypeError('type error'); typeError.stack = 'stacktrace'; expect(normalizeError(typeError, defaultLogger)).toEqual(typeError); expect(defaultLogger.warn).not.toHaveBeenCalled(); });
185-235
: Comprehensive tests for Bugsnag exception creation!The tests handle both valid and invalid stack traces well. Consider adding a test case for different error types (TypeError, ReferenceError) to ensure proper errorClass assignment.
it('should handle different error types', () => { const typeError = new TypeError('type error'); typeError.stack = 'TypeError: type error\n at test (file.js:1:1)'; expect(createBugsnagException(typeError, 'prefix')).toEqual({ errorClass: 'TypeError', message: 'prefixtype error', type: 'browserjs', stacktrace: [{ file: 'file.js', method: 'test', lineNumber: 1, columnNumber: 1, }], }); });packages/analytics-js/__tests__/services/StoreManager/Store.test.ts (1)
67-76
: LGTM! Well-structured test for legacy data handling.The test case effectively verifies the warning behavior for legacy encrypted values. Consider adding a test case for non-encrypted values to ensure no false positives.
+ it('should not log a warning for non-encrypted values', () => { + const spy = jest.spyOn(defaultLogger, 'warn'); + engine.setItem('name.id.queue', '"normalValue"'); + + store.get('queue'); + expect(spy).not.toHaveBeenCalled(); + });packages/analytics-js/src/components/eventRepository/EventRepository.ts (3)
47-49
: Consider reordering constructor parameters for better maintainability.While the changes to make dependencies required are good, consider grouping related parameters together. The
httpClient
parameter could be moved next tostoreManager
since they're both infrastructure dependencies.constructor( pluginsManager: IPluginsManager, storeManager: IStoreManager, - httpClient: IHttpClient, errorHandler: IErrorHandler, - logger: ILogger, + logger: ILogger, + httpClient: IHttpClient, )Also applies to: 53-53
62-89
: Extract queue initialization logic for better readability.The queue initialization code is repetitive and could benefit from extraction into a helper method.
private initQueue( prefix: string, additionalArgs: unknown[] = [] ): any { return this.pluginsManager.invokeSingle( `${prefix}.init`, state, ...additionalArgs, this.httpClient, this.storeManager, this.errorHandler, this.logger, ); }Usage:
this.dataplaneEventsQueue = this.initQueue(DATA_PLANE_QUEUE_EXT_POINT_PREFIX); this.dmtEventsQueue = this.initQueue(DMT_EXT_POINT_PREFIX, [this.pluginsManager]); this.destinationsEventsQueue = this.initQueue( DESTINATIONS_QUEUE_EXT_POINT_PREFIX, [this.pluginsManager, this.dmtEventsQueue] );
173-185
: Extract callback handling logic for reusability.The callback validation and invocation logic could be reused across the codebase. Consider extracting it into a utility function.
// utilities/callbacks.ts export const safelyInvokeCallback = ( callback: unknown, args: unknown[], apiName: string, logger: ILogger ): void => { if (!isDefined(callback)) return; if (isFunction(callback)) { try { callback(...args); } catch (error) { logger.error(CALLBACK_INVOKE_ERROR(apiName), error); } } else { logger.error(INVALID_CALLBACK_FN_ERROR(apiName)); } }; // Usage in EventRepository const apiName = `${event.type.charAt(0).toUpperCase()}${event.type.slice(1)}${API_SUFFIX}`; safelyInvokeCallback(callback, [dpQEvent], apiName, this.logger);packages/analytics-js/__tests__/components/eventRepository/EventRepository.test.ts (1)
97-103
: Consider reducing duplication in test setup.The EventRepository constructor is instantiated with the same parameters in multiple test cases. Consider extracting this into a test helper function to improve maintainability.
Example implementation:
const createEventRepository = ( pluginsManager = defaultPluginsManager, storeManager = defaultStoreManager, ) => new EventRepository( pluginsManager, storeManager, defaultHttpClient, defaultErrorHandler, defaultLogger, ); // Usage in tests const eventRepository = createEventRepository(); // Or with custom managers const eventRepository = createEventRepository(mockPluginsManager);Also applies to: 140-146, 156-162, 189-195, 207-213, 232-238, 256-262, 295-301, 316-322, 358-364, 383-389, 397-403
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (14)
packages/analytics-js/__tests__/components/capabilitiesManager/CapabilitiesManager.test.ts
(3 hunks)packages/analytics-js/__tests__/components/configManager/ConfigManager.test.ts
(4 hunks)packages/analytics-js/__tests__/components/core/Analytics.test.ts
(6 hunks)packages/analytics-js/__tests__/components/eventRepository/EventRepository.test.ts
(9 hunks)packages/analytics-js/__tests__/services/ErrorHandler/event.test.ts
(1 hunks)packages/analytics-js/__tests__/services/ErrorHandler/utils.test.ts
(1 hunks)packages/analytics-js/__tests__/services/StoreManager/Store.test.ts
(7 hunks)packages/analytics-js/src/components/configManager/ConfigManager.ts
(8 hunks)packages/analytics-js/src/components/core/Analytics.ts
(10 hunks)packages/analytics-js/src/components/eventRepository/EventRepository.ts
(4 hunks)packages/analytics-js/src/constants/logMessages.ts
(8 hunks)packages/analytics-js/src/services/ErrorHandler/event/event.ts
(1 hunks)packages/analytics-js/src/state/slices/lifecycle.ts
(2 hunks)packages/analytics-js/src/state/slices/loadOptions.ts
(0 hunks)
💤 Files with no reviewable changes (1)
- packages/analytics-js/src/state/slices/loadOptions.ts
🚧 Files skipped from review as they are similar to previous changes (4)
- packages/analytics-js/tests/components/core/Analytics.test.ts
- packages/analytics-js/src/constants/logMessages.ts
- packages/analytics-js/src/components/configManager/ConfigManager.ts
- packages/analytics-js/src/components/core/Analytics.ts
🧰 Additional context used
📓 Learnings (2)
packages/analytics-js/__tests__/components/capabilitiesManager/CapabilitiesManager.test.ts (2)
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1730
File: packages/analytics-js/__tests__/components/capabilitiesManager/CapabilitiesManager.test.ts:129-129
Timestamp: 2024-11-12T15:14:23.319Z
Learning: When testing code that relies on imported constants, ensure the mock is applied correctly before the test cases run to avoid issues with timing or execution flow.
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1730
File: packages/analytics-js/__tests__/components/capabilitiesManager/CapabilitiesManager.test.ts:129-129
Timestamp: 2024-11-12T15:14:23.319Z
Learning: When testing code that relies on imported constants, use module mocking to control the values of those constants during the test.
packages/analytics-js/src/services/ErrorHandler/event/event.ts (1)
Learnt from: saikumarrs
PR: rudderlabs/rudder-sdk-js#1907
File: packages/analytics-js/src/services/ErrorHandler/ErrorHandler.ts:172-174
Timestamp: 2024-11-12T15:14:23.319Z
Learning: The function `onError` in `packages/analytics-js/src/services/ErrorHandler/ErrorHandler.ts` is acceptable as currently implemented, and refactoring suggestions are not required unless necessary.
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Bundle size checks
🔇 Additional comments (21)
packages/analytics-js/__tests__/components/capabilitiesManager/CapabilitiesManager.test.ts (1)
43-47
: LGTM! Clean constructor parameter update.The addition of
defaultHttpClient
as a required parameter aligns well with the PR's objective of centralizing error reporting in the core module.packages/analytics-js/__tests__/components/configManager/ConfigManager.test.ts (4)
147-158
: LGTM! Good test coverage for invalid getSourceConfig.The test properly validates that non-function values for
getSourceConfig
are caught and logged appropriately.
165-165
: LGTM! Source name field addition.The addition of the
name
field toexpectedSourceState
aligns with the updated Source type.
192-211
: LGTM! Comprehensive error handling tests.Good coverage of different error scenarios for source config parsing and validation.
303-342
: LGTM! Thorough validation of CDN URLs.The tests properly verify that invalid CDN URLs are caught early and prevent further initialization.
packages/analytics-js/__tests__/services/ErrorHandler/utils.test.ts (1)
1-715
: LGTM! Comprehensive test coverageThe test file provides thorough coverage of error handling utilities with well-structured test cases. The tests cover various scenarios including:
- Error event payload generation
- Error notification filtering
- Device and user details handling
- Error instance management
- URL and release stage handling
packages/analytics-js/src/services/ErrorHandler/event/event.ts (2)
1-12
: LGTM! Well-organized imports and constants.The imports are properly typed and organized, and the constants are clearly defined.
84-91
: LGTM! Well-organized exports.The exports are clearly organized with helpful comments indicating which exports are for testing purposes.
packages/analytics-js/__tests__/services/ErrorHandler/event.test.ts (2)
1-10
: Well-structured imports and test organization!The imports are clearly organized, properly separating the mock dependencies from the actual implementations being tested.
30-45
: Excellent test coverage for string conversion!The test suite thoroughly covers all possible input types and edge cases, ensuring robust string conversion behavior.
packages/analytics-js/__tests__/services/StoreManager/Store.test.ts (3)
4-7
: LGTM! Dependencies align with the core error reporting refactor.The new imports and plugin setup correctly implement the architectural changes of moving error reporting to the core module.
Also applies to: 29-30
105-106
: LGTM! Consistent application of new dependencies.The errorHandler and logger parameters are consistently added across all test cases, maintaining the integrity of the test suite.
Also applies to: 109-109, 122-123, 126-126, 137-138, 141-141, 166-167, 170-170
39-40
: Consider adding test cases for error handler and logger interactions.While the dependencies are correctly added, consider adding test cases that verify:
- Error handler's interaction with Store operations
- Logger's behavior during Store operations
- Plugin manager's involvement in Store lifecycle
Also applies to: 43-43
✅ Verification successful
The review comment is valid - test coverage for error handler and logger is minimal
Current test suite only verifies:
- Basic initialization of error handler and logger in constructor
- One logger.warn case for legacy encrypted values
Missing test coverage:
- Error handler's behavior during storage operations failures
- Logger's messages during critical operations
- Error propagation through the error handler
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Check for existing error handling test coverage rg -l "errorHandler|logger.*test" "packages/analytics-js/__tests__/"Length of output: 431
Script:
#!/bin/bash # Check test cases in Store.test.ts rg "describe|it\(" -A 5 "packages/analytics-js/__tests__/services/StoreManager/Store.test.ts" # Look for actual error handler and logger usage in tests rg "errorHandler|logger" -B 2 -A 2 "packages/analytics-js/__tests__/services/StoreManager/Store.test.ts"Length of output: 4184
packages/analytics-js/src/components/eventRepository/EventRepository.ts (2)
11-14
: LGTM! Making error handling and logging mandatory.The changes align well with the PR objective of centralizing error reporting in the core module by making error handling and logging required dependencies.
Also applies to: 28-29
152-170
: Verify error handling consistency across queue operations.The error handling changes look good, but we should verify that similar changes have been made in other queue-related components for consistency.
✅ Verification successful
Error handling is consistently implemented across queue operations
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for queue-related files and check their error handling patterns rg -l "Queue" packages/analytics-js/src/ | xargs rg "errorHandler|logger" -A 5Length of output: 44682
packages/analytics-js/src/state/slices/lifecycle.ts (2)
3-3
: LGTM!Clean import of the POST_LOAD_LOG_LEVEL constant, following the project's import style.
13-13
: Verify the POST_LOAD_LOG_LEVEL constant usage across the codebase.The change from hardcoded 'ERROR' to POST_LOAD_LOG_LEVEL aligns with centralizing error handling in the core module. However, let's verify the constant's usage and potential impact.
✅ Verification successful
POST_LOAD_LOG_LEVEL constant is properly implemented and used consistently
The constant is correctly defined in Logger.ts and properly used across the codebase. The change from hardcoded 'ERROR' to POST_LOAD_LOG_LEVEL improves maintainability by centralizing the default log level configuration.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify POST_LOAD_LOG_LEVEL usage and potential dependencies on 'ERROR' level # Check the POST_LOAD_LOG_LEVEL constant definition echo "Checking POST_LOAD_LOG_LEVEL definition:" rg -p "POST_LOAD_LOG_LEVEL.*=" services/Logger # Find any remaining hardcoded 'ERROR' log levels that might need updating echo -e "\nChecking for remaining hardcoded ERROR levels:" rg -p "logLevel.*['\"]ERROR['\"]" # Find all consumers of logLevel to verify compatibility echo -e "\nChecking logLevel usage:" rg -p "logLevel" -A 3Length of output: 123043
Script:
#!/bin/bash # Find POST_LOAD_LOG_LEVEL definition and usages echo "Searching for POST_LOAD_LOG_LEVEL definition:" rg -p "POST_LOAD_LOG_LEVEL.*=" echo -e "\nSearching for POST_LOAD_LOG_LEVEL usages:" rg -p "POST_LOAD_LOG_LEVEL"Length of output: 936
packages/analytics-js/__tests__/components/eventRepository/EventRepository.test.ts (4)
8-10
: LGTM! Import changes align with core error reporting.The new imports for errorHandler, logger, and httpClient are correctly added to support the migration of error reporting functionality to the core module.
315-332
: LGTM! Comprehensive error handling test coverage.The new test cases effectively verify:
- Logging of errors for invalid callbacks
- Proper handling of errors thrown by callback functions
This aligns well with the PR's objective of improving error handling in the core module.
Also applies to: 334-354
107-114
: LGTM! Consistent assertion style.The assertions have been updated to use Jest's preferred
toHaveBeenCalled
syntax, and the parameters consistently include the new error handling dependencies.Also applies to: 116-124, 126-134, 152-152, 185-185, 203-203, 222-226, 247-250, 269-279, 281-288, 308-312, 328-331, 350-353, 378-378, 393-393, 411-412
Line range hint
1-414
: Verify error handling coverage.While the test coverage for error handling is good, let's verify if all potential error scenarios are covered.
Run this script to check for error handling patterns in the codebase that might need test coverage:
✅ Verification successful
Error handling coverage is complete ✅
The test suite adequately covers all error scenarios present in the EventRepository implementation, specifically:
- Invalid callback function errors
- Callback execution errors
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for error handling patterns in the EventRepository implementation ast-grep --pattern 'try { $$$ } catch' packages/analytics-js/src/components/eventRepository/EventRepository.ts # Search for throw statements that might need error handling tests ast-grep --pattern 'throw new Error($$$)' packages/analytics-js/src/components/eventRepository/EventRepository.ts # Search for error logging calls that should have corresponding tests rg 'logger\.(error|warn)' packages/analytics-js/src/components/eventRepository/EventRepository.tsLength of output: 459
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
packages/analytics-js/src/components/configManager/types.ts (1)
87-90
: Consider adding JSDoc comments for the updated method signature.The enhanced signature with proper typing will improve error handling capabilities. Consider adding documentation to explain the expected format of the response and the purpose of the details parameter.
Add JSDoc comments like this:
+ /** + * Process the configuration response from the server + * @param response The configuration response that can be either parsed JSON, raw string, or undefined + * @param details Additional response details including status code and headers + */ processConfig: ( response: SourceConfigResponse | string | undefined, details?: ResponseDetails, ) => void;packages/analytics-js/src/components/configManager/ConfigManager.ts (1)
82-108
: Consider adding error logging for null CDN URLs.While the early returns prevent undefined behavior, adding error logging would help with debugging when CDN URLs are null.
if (isNull(intgCdnUrl)) { + this.logger.error('Failed to determine integrations CDN path'); return; } let pluginsCDNPath: Nullable<string> | undefined; if (!__BUNDLE_ALL_PLUGINS__) { // determine the path to fetch remote plugins from pluginsCDNPath = getPluginsCDNPath( APP_VERSION, lockPluginsVersion as boolean, pluginsSDKBaseURL, this.logger, ); } if (pluginsCDNPath === null) { + this.logger.error('Failed to determine plugins CDN path'); return; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
packages/analytics-js/__tests__/components/configManager/ConfigManager.test.ts
(5 hunks)packages/analytics-js/src/components/configManager/ConfigManager.ts
(7 hunks)packages/analytics-js/src/components/configManager/types.ts
(2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: Security and code quality checks
- GitHub Check: Bundle size checks
🔇 Additional comments (9)
packages/analytics-js/src/components/configManager/types.ts (2)
4-7
: LGTM! Clean import structure.The new imports from the common types package are well-organized and properly scoped.
83-84
: Verify implementations of IConfigManager interface.Making
errorHandler
andlogger
required properties aligns well with the PR's objective of centralizing error handling. However, this is a breaking change.Let's verify all implementations of this interface to ensure they're updated:
✅ Verification successful
Interface change matches implementation
The only implementation of
IConfigManager
(ConfigManager class) already handleserrorHandler
andlogger
as required properties, properly initializing them in the constructor and using them throughout. This interface change is safe.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for classes implementing IConfigManager ast-grep --pattern 'class $_ implements IConfigManager { $$$ }' # Also search for potential test mocks rg -l "Mock<IConfigManager>"Length of output: 21301
packages/analytics-js/src/components/configManager/ConfigManager.ts (6)
7-12
: LGTM! Making error handling and logging required.The change from optional to required properties for
errorHandler
andlogger
aligns with the PR objective of moving error reporting to the core module. This ensures consistent error handling and logging throughout the application.Also applies to: 44-45
47-53
: LGTM! Constructor updated to enforce required dependencies.The constructor signature change ensures that error handling and logging capabilities are properly initialized at instantiation time.
58-58
: LGTM! Simplified logger access.Removed optional chaining as
logger
is now a required property.
141-142
: LGTM! Simplified error handling.Removed the
shouldAlwaysThrow
parameter and simplified error handling logic, which aligns with moving error reporting to the core module.
149-157
: LGTM! Enhanced type safety and error handling.The changes improve type safety with proper annotations and make error handling more consistent. The addition of the source name property enhances the stored source information.
Also applies to: 166-166, 169-169, 174-174, 180-180, 195-195
222-223
: LGTM! Improved error handling for invalid source config function.Error is now logged instead of thrown, which aligns with the PR objective of moving error reporting to the core module.
packages/analytics-js/__tests__/components/configManager/ConfigManager.test.ts (1)
Line range hint
148-394
: LGTM! Comprehensive test coverage added.The new test cases thoroughly cover:
- Error handling for invalid source config function
- CDN URL validation
- Promise-based source config handling
- Various error scenarios
This ensures the robustness of the error reporting functionality moved to the core module.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
packages/analytics-js/src/services/PluginEngine/PluginEngine.ts (1)
126-126
: Consider adding debug logging for dependency resolution.While error handling for missing dependencies is good, adding debug logging for successful dependency resolution would help with troubleshooting.
this.logger.error(PLUGIN_DEPS_ERROR(PLUGIN_ENGINE, plugin.name, notExistDeps)); +this.logger.debug(`Successfully resolved dependencies for plugin: ${plugin.name}`);
packages/analytics-js/__tests__/services/PluginEngine/PluginEngine.test.ts (1)
126-168
: LGTM: Thorough unregistration error handling testsComprehensive test coverage for unregistration scenarios, including edge cases and internal state validation. The error message for internal inconsistency is particularly helpful for debugging.
Consider adding a test case for unregistering a plugin with dependencies to ensure proper cleanup of the dependency graph.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/analytics-js/__tests__/services/PluginEngine/PluginEngine.test.ts
(5 hunks)packages/analytics-js/src/services/PluginEngine/PluginEngine.ts
(8 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: Bundle size checks
- GitHub Check: Security and code quality checks
🔇 Additional comments (7)
packages/analytics-js/src/services/PluginEngine/PluginEngine.ts (5)
32-34
: LGTM! Making logger required improves error handling reliability.The change from optional to required logger ensures consistent error reporting across the SDK, aligning with the PR's objective to centralize error handling in the core module.
Also applies to: 34-41
49-50
: LGTM! Error handling for plugin registration is robust.The error logging implementation correctly handles plugin registration failures while maintaining the throws/non-throws behavior.
91-92
: LGTM! Comprehensive error handling for plugin unregistration.The implementation properly handles both plugin not found and internal engine error scenarios.
Also applies to: 103-104
182-185
: LGTM! Graceful error handling in plugin invocation.The implementation ensures plugin failures are properly logged without breaking the application, as previously confirmed.
202-202
: LGTM! Default plugin engine instantiation updated correctly.The constructor parameter order has been properly updated to match the new signature.
packages/analytics-js/__tests__/services/PluginEngine/PluginEngine.test.ts (2)
2-2
: LGTM: Logger integration aligns with centralized error handlingThe addition of the logger dependency to PluginEngine is consistent with the PR's objective of centralizing error reporting functionality.
Also applies to: 39-39
58-90
: LGTM: Comprehensive error handling test coverageWell-structured test cases that:
- Cover both throwing and logging scenarios
- Properly handle TypeScript type checking
- Test error messages for clarity and accuracy
packages/analytics-js/__tests__/services/PluginEngine/PluginEngine.test.ts
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (5)
packages/analytics-js/src/components/utilities/callbacks.ts (2)
5-24
: Consider improving type safetyThe current implementation could benefit from stronger typing:
- Consider constraining the callback type to a specific function signature
- Consider capturing and handling the callback's return value
- Add type for the error object in catch block
-const safelyInvokeCallback = ( - callback: unknown, - args: unknown[], +type CallbackFunction = (...args: any[]) => void; + +const safelyInvokeCallback = ( + callback: CallbackFunction | unknown, + args: unknown[], apiName: string, logger: ILogger, ): void => { if (!isDefined(callback)) { return; } - if (isFunction(callback)) { + if (isFunction(callback) && callback instanceof Function) { try { callback(...args); } catch (error) { - logger.error(CALLBACK_INVOKE_ERROR(apiName), error); + const err = error instanceof Error ? error : new Error(String(error)); + logger.error(CALLBACK_INVOKE_ERROR(apiName), err); } } else { logger.error(INVALID_CALLBACK_FN_ERROR(apiName)); } };
1-26
: Implementation aligns well with PR objectivesThis utility function successfully contributes to the PR's goal of improving error handling by:
- Containing errors locally instead of throwing them to global handlers
- Using structured logging through the required logger instance
- Providing consistent error handling for callback invocations across the SDK
packages/analytics-js/src/components/eventRepository/EventRepository.ts (1)
27-28
: LGTM! Consider enhancing constructor documentation.The changes to make error handler and logger required dependencies, along with the addition of httpClient parameter, improve the robustness of the class. This aligns well with the PR's objective of centralizing error handling.
Consider updating the constructor's JSDoc to document the new
httpClient
parameter:/** * * @param pluginsManager Plugins manager instance * @param storeManager Store Manager instance + * @param httpClient HTTP client instance * @param errorHandler Error handler object * @param logger Logger object */
Also applies to: 46-48
packages/analytics-js/__tests__/services/ErrorHandler/utils.test.ts (2)
30-42
: Add edge cases to breadcrumb tests.The
createNewBreadcrumb
test only covers the happy path. Consider adding tests for edge cases such as empty messages, special characters, and very long messages.describe('createNewBreadcrumb', () => { it('should create and return a breadcrumb', () => { const msg = 'sample message'; const breadcrumb = createNewBreadcrumb(msg); expect(breadcrumb).toStrictEqual({ metaData: {}, type: 'manual', timestamp: expect.any(Date), name: msg, }); }); + + it('should handle empty messages', () => { + const breadcrumb = createNewBreadcrumb(''); + expect(breadcrumb.name).toBe(''); + }); + + it('should handle very long messages', () => { + const longMsg = 'a'.repeat(1000); + const breadcrumb = createNewBreadcrumb(longMsg); + expect(breadcrumb.name).toBe(longMsg); + }); });
606-618
: Add test cases for error message patterns.The
isAllowedToBeNotified
test suite could benefit from more comprehensive test cases covering different error message patterns.const testCases = [ ['dummy error', true, 'should allow generic errors'], ['The request failed', false, 'should not allow request failures'], ['', true, 'should allow empty messages'], ['Network request failed', true, 'should allow network errors'], + ['Error: Failed to fetch', true, 'should allow fetch errors'], + ['TypeError: Cannot read property', true, 'should allow type errors'], + ['SyntaxError: Unexpected token', true, 'should allow syntax errors'], + ['The request was aborted', false, 'should not allow aborted requests'], + ['Request timed out', false, 'should not allow timeout messages'], ];
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
packages/analytics-js/__tests__/services/ErrorHandler/utils.test.ts
(1 hunks)packages/analytics-js/src/components/core/Analytics.ts
(9 hunks)packages/analytics-js/src/components/eventRepository/EventRepository.ts
(4 hunks)packages/analytics-js/src/components/utilities/callbacks.ts
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: Security and code quality checks
- GitHub Check: Bundle size checks
🔇 Additional comments (14)
packages/analytics-js/src/components/core/Analytics.ts (6)
103-108
: LGTM! Proper initialization of error handling capabilities.The changes improve error handling by initializing it early in the lifecycle and properly injecting dependencies.
138-138
: LGTM! Proper use of nullish coalescing for logger initialization.The change ensures proper logging level is set early in the lifecycle.
250-251
: LGTM! Consistent error handling in UserSessionManager.The changes maintain consistency with the core error handling pattern.
256-258
: LGTM! Proper dependency injection in EventRepository.The changes ensure consistent error handling and service availability.
324-333
: Review the usage of window object in callback.The TODO comment correctly identifies that passing the window object to the callback function could prevent multiple SDK instances in the same page. This should be addressed in a future update.
Consider refactoring to avoid passing the window object. This would enable better support for multiple SDK instances.
468-468
: LGTM! Consistent error handling pattern.The changes improve maintainability by using predefined error message constants and following a consistent error handling pattern.
Also applies to: 481-481
packages/analytics-js/src/components/utilities/callbacks.ts (3)
1-3
: Well-structured imports with good separation of concerns!The imports are well-organized, utilizing shared utilities and types from a common package, with centralized error messages.
5-10
: Well-implemented error handling with proper logging!The function follows good practices with early returns, proper error handling, and consistent logging.
26-26
: Clean and explicit export!The named export follows TypeScript best practices.
packages/analytics-js/src/components/eventRepository/EventRepository.ts (2)
151-173
: LGTM! Improved callback handling.The changes enhance error handling consistency and the use of
safelyInvokeCallback
is a good practice for safely executing user-provided callbacks. This aligns with the PR's goal of suppressing instrumentation errors.The separation between data plane and destination queues is maintained while ensuring consistent error handling across both paths.
61-88
: Verify error handling for queue initialization.The removal of local try-catch blocks suggests error handling has been moved to a higher level. Let's verify this change is intentional and errors are properly handled.
Let's check if error handling is implemented in the plugin manager or queue implementations:
✅ Verification successful
Error handling verification completed successfully
The removal of local try-catch blocks is justified as error handling is properly implemented through the injected errorHandler utility. The system uses a robust, centralized error handling mechanism that:
- Normalizes errors consistently
- Provides proper error reporting
- Filters unnecessary error notifications
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for error handling in plugin manager and queue implementations rg -A 5 "invokeSingle.*error" packages/analytics-js/src/ rg -A 5 "(DATA_PLANE_QUEUE|DESTINATIONS_QUEUE|DMT_EXT_POINT).*error" packages/analytics-js/src/Length of output: 156
Script:
#!/bin/bash # Find invokeSingle implementation ast-grep --pattern 'invokeSingle($_) { $$$ }' # Search for error handler usage in queue-related files fd -e ts -e js queue --exec rg -i "errorHandler" {} -A 5 # Look for try-catch blocks in queue-related code fd -e ts -e js queue --exec rg "try\s*{" {} -A 10Length of output: 2062
Script:
#!/bin/bash # Search for try-catch blocks with fixed pattern fd -e ts -e js queue --exec rg "try {" {} -A 10 # Look for PluginsManager error handling rg -g "**/*PluginsManager*" "try {" -A 10 # Search for error handler implementation rg -g "**/*errorHandler*" "class|function|const" -A 5Length of output: 10169
packages/analytics-js/__tests__/services/ErrorHandler/utils.test.ts (3)
1-24
: LGTM! Well-structured test file setup.The file structure is clean with appropriate imports and test setup. The UUID mock ensures consistent test outcomes.
653-714
: LGTM! Comprehensive test coverage for user and device details.The test suites for
getUserDetails
andgetDeviceDetails
are well-structured with good coverage of both happy path and fallback scenarios.
275-584
: 🛠️ Refactor suggestionImprove test maintainability by extracting test data setup.
The
getBugsnagErrorEvent
test contains a large amount of setup code and assertions. This makes the test harder to maintain and understand.Extract the test data setup into helper functions:
+const setupTestState = () => { + state.session.sessionInfo.value = { id: 123 }; + state.context.app.value.installType = 'cdn'; + state.autoTrack.pageLifecycle.visitId.value = 'test-visit-id'; + state.context.library.value.snippetVersion = 'sample_snippet_version'; + state.context.locale.value = 'en-US'; + state.context.userAgent.value = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'; + // ... rest of the state setup +}; + +const createTestException = () => ({ + errorClass: 'Error', + message: 'dummy message', + type: 'browserjs', + stacktrace: [ + { + file: 'https://example.com/sample.js', + method: 'Object.<anonymous>', + lineNumber: 1, + columnNumber: 1, + }, + ], +}); + describe('getBugsnagErrorEvent', () => { it('should return the error event payload', () => { - state.session.sessionInfo.value = { id: 123 }; - // ... rest of the state setup + setupTestState(); + const exception = createTestException(); // ... rest of the test }); + + it('should handle missing optional fields', () => { + setupTestState(); + const exception = createTestException(); + delete state.context.screen.value; + // ... test with missing fields + }); });Likely invalid or redundant comment.
…porting-to-core-sdk-2826
Quality Gate passedIssues Measures |
Closing it in place of #2011. |
PR Description
I've moved the error reporting functionality to the core SDK and deleted the ErrorReporting and Bugsnag plugins.
The SDK can report errors as soon as it loads and don't have to wait for plugins to finish loading.
Now, there are no parts in the SDK that throw errors left to be handled by the global exception handlers.
Additional updates:
Linear task (optional)
https://linear.app/rudderstack/issue/SDK-2826/move-error-reporting-functionality-to-the-core-sdk
Cross Browser Tests
Please confirm you have tested for the following browsers:
Sanity Suite
Security
Summary by CodeRabbit
Summary by CodeRabbit
Release Notes
Removed Plugins
Error Handling Improvements
Dependency Management
Performance Optimizations
Testing Enhancements