Skip to content
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

[BUG] Consuming trackEvent from useAppInsights results in DynamicProto error #121

Open
DZetko opened this issue Oct 22, 2024 · 1 comment

Comments

@DZetko
Copy link

DZetko commented Oct 22, 2024

Description/Screenshot
I have below React component

`
import React from "react";
import { useAppInsightsContext } from "@microsoft/applicationinsights-react-js";
const TestComponent = () => {
const { trackEvent } = useAppInsightsContext();

function onClick() {
    trackEvent({ name: "TestComponent test" });
}

return (
    <div className="App">
        <div>
            <button onClick={onClick}>Add Number</button>
        </div>
    </div>
);

};
export default TestComponent;
`

When I click the Add Number button, I am getting bellow error message:
Image

My Application Insights instance is set up as below

Image

Steps to Reproduce

  • OS/Browser: MacOS Sonoma 14.6.1, Chrome 129.0.6668.100 (arm64)
  • React Version: 17.0.2, same happens with 18.3.1
  • SDK Version [e.g. 22]: 17.3.3
  • How you initialized the SDK:

Expected behavior
Error should not be displayed and event should be sent to Application Insights.

Additional context
Add any other context about the problem here.

When using reactPlugin instance directly and calling reactPlugin.trackEvent works.

@MSNev
Copy link
Contributor

MSNev commented Oct 23, 2024

When you see this error this is caused by either of the following

  • Loading different versions of the SDK, where you initialize with instance 1 and then the code is overwritten with instance 2
  • The dynamic prototypes are not actually created until the first instance is created, so this can also occur if your trying to use an uninitialized instance -- like calling the "object" passing an uninitialized "this" instance.

Personally, I've only seen the first case where a combination of npm and snippet was being used, so your local code is including 1 copy of the source code and using that, but the SDK Loader comes along behind you and "overwrites" the global namespace of the code "Microsoft.ApplicationInsights.XXX".

The latest version of the code (v3.x) is aware of this situation and the default "initialization" code added to the top of each bundle trys to avoid "overwriting" the class / object definitions. By

  • Unique major version # namespace is the default population Microsoft.ApplicaitonInsights3 and then it "populates" the Microsoft.ApplicationInsights
    • v3.x Only set the "root" Microsoft.ApplicationInsights class / object name if it's not present (first write wins)
    • v2.x (for backwards compatibility reasons) it's the reverse and it "always" overwrites the root namespace (last write wins) 😦 , not ideal and can lead to your situation
    • v1.x (original) -- it only always loads and overwrites the root namespace (we have not released a 1.x version for years and is considered to be deprecated
  • To "try" and help diagnose this situation when it occurs v3.x has some "additional" debugging only references added to the "root" namespace Microsoft.Application.__ms$mod__ which identifies the "order" of the SDK's being loaded and which version was used to populate the root namespace. (But this is only added if you are loading from the CDN as it's part of the UMD heading (see all of that code at the top with var names of baseNs, modName etc

Image

So what does all this mean?

Please check whether your runtime is

  • Loading more than 1 version of the SDK at any point (this can be a race condition, as mentioned above) -- your code is using npm but then something is also injecting the SDK Loader and you end up loading (and replacing) the SDK instance (F12 - network tab is your friend for this one)
  • You wrappers are attempting to call the prototype of the "classes" directly (via apply or call) rather than via the normal initialized object instances. Sometimes just creating a "dummy" SDK instance (so that the dynamic prototype stubs are populated) is enough (other times not) - we play this game with some of our tests. The easiest solution is to just initialize and call the functions directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants