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

telemetry.properties.result reflects "Failed" even if the operation was canceled and UserCancledError was thrown #1306

Closed
shsuman opened this issue Dec 13, 2022 · 9 comments · Fixed by #1443

Comments

@shsuman
Copy link
Member

shsuman commented Dec 13, 2022

Here is one of our sample telemetry event being captured in Kusto:

{
  "result": "Failed",
  "isactivationevent": "false",
  "stack": "n.<anonymous> extension.js:2:1981387\ns extension.js:2:1980640",
  "contextvalue": "Uri",
  "error": "o",
  "errormessage": "Operation cancelled.",
  "laststep": "ApplicationShell.showInformationMessage",
}

It is clear that the operation was canceled from the error message and the laststep property but the result property says "Failed" instead of "Canceled"

My best guess is that its because of this piece of code here
utils\src\parseError.ts at parseError() function

if (error.constructor !== Object) {
      errorType = error.constructor.name;
}

A constructor.name comparison has been relied upon to check whether its a UserCanceledError or not. This doesn't work with webpack as the constructor names are minified.

@shsuman shsuman changed the title telemetry.porperties.result reflects "Failed" even if the operation was canceled and UserCancledError was thrown telemetry.properties.result reflects "Failed" even if the operation was canceled and UserCancledError was thrown Dec 20, 2022
@alexweininger
Copy link
Member

alexweininger commented Dec 21, 2022

Thanks for reporting the issue. We have also configured Webpack to not mangle function names as you have done in your fix.

https://github.com/microsoft/vscode-azuretools/blob/main/dev/src/webpack/getDefaultWebpackConfig.ts#L102-L103

Without configuring Webpack properly, I'm not sure how to fix this.

@shsuman
Copy link
Member Author

shsuman commented Dec 22, 2022

I am a little nit confused here. You are not exporting minified code, are you ? I am looking inside the node_modules/@microsoft/vscode-azext-utils folder and its all JS files.

Well, as for a fix, why not use instanceof operator ? :)

@alexweininger
Copy link
Member

I am a little nit confused here. You are not exporting minified code, are you ? I am looking inside the node_modules/@microsoft/vscode-azext-utils folder and its all JS files.

We are not exporting minified code.

Well, as for a fix, why not use instanceof operator ? :)

Unfortunately, instanceof breaks when objects are passed between different instances of the utils package (ex: between extensions).

@shsuman
Copy link
Member Author

shsuman commented Apr 5, 2023

I think if there is a limitation, then we will stick to the webpack configuration. You may close the issue now :)
Thanks for the all the information :)

@alexweininger
Copy link
Member

Were you able to fix this issue by altering your webpack config?

@shsuman
Copy link
Member Author

shsuman commented Apr 6, 2023

Yes. Here's the webpack changes that we made:

 optimization: {
        minimize: true,
        /**
         * **DO NOT REMOVE**
         * Workaround for https://github.com/Azure/ms-rest-nodeauth/issues/83
         */
        minimizer: [
            new TerserPlugin({
                terserOptions: {
                    keep_fnames: /AbortSignal|UserCancelledError/,
                    keep_classnames: /AbortSignal|UserCancelledError/
                }
            })
        ]
    },

@StephenWeatherford
Copy link
Contributor

I had thought we'd placed a property on UserCancelledError to avoid this issue:

export class UserCancelledError extends Error {
  public get isUserCancelledError() { return true; }
...

Then clients can simply check for the existence of this property and name mangling won't matter.

@alexweininger
Copy link
Member

I had thought we'd placed a property on UserCancelledError to avoid this issue:

export class UserCancelledError extends Error {
  public get isUserCancelledError() { return true; }
...

Then clients can simply check for the existence of this property and name mangling won't matter.

It doesn't look like we ever did that. And I agree we should do that so runtime behavior isn't impacted by bundling configuration.

@bwateratmsft
Copy link
Contributor

It might be overkill for the use case, but we may also benefit from having another method like this, that checks the isUserCancelledError property on the input object:

function isUserCancelledError(foo: unknown): foo is UserCancelledError {
    // ...
}

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

Successfully merging a pull request may close this issue.

4 participants