theron-wang/VS2022-Editor-Support-for-Tailwind-CSS

'Object reference not set to an instance of an object' exception when Intellisense triggered

Closed this issue · 15 comments

After updating the extension to the latest version, I saw the auto-complete trigger briefly but then an Object reference not set to an instance of an object dialog popped up (and pops up on each subsequent key press)

259448259-aa72a967-c2ba-4541-8eea-a664f78400a5

It's likely our custom config that is causing the problem. If I replace the contents of tailwind.config.js with tailwind.dev.config.js, the error above does not occur and intellisense works as expected.

Tailwind configs:

tailwind.config.js

const defaultConfig = require('./tailwind.dev.config');

module.exports = {
    ...defaultConfig,
    plugins: [require("@tailwindcss/forms")]
};

tailwind.dev.config.js

module.exports = {
  darkMode: "media",
  theme: {
    extend: {
      colors: {
...
      },
    },
  },
};

edit: remove noise

The latest update fixes the exception, but Intellisense does not show the custom values if you use ...defaultConfig. I will add support for that in the future; in the meantime, if you need the custom values, you can right click on tailwind.dev.config.js in the Solution Explorer and click 'Set as TailwindCSS configuration file', which will tell Intellisense to look at that file instead of tailwind.config.js.

I hope this helps, and thanks again for reporting the bug!

This problem still persists.

IDE: Microsoft Visual Studio Enterprise 2022 (64-bit) - Current
Version: 17.7.1
Extension Version: 1.1.7.4

Symptoms:

  • NRE when triggering intellisense.
  • In a .css, and .cshtml file, the extension works fine. But in a .razor file, I get the NRE.

Configuration:
My Tools -> Options settings are all default.

{
 "ConfigurationFile": "tailwind.config.js",
 "InputCssFile": "wwwroot\\css\\tailwind.css",
 "OutputCssFile": "wwwroot\\css\\tailwind.output.css"
}

There are no entries in the ActivityLog.xml, and no other logs that I can see; and nothing in the Extensions filter, for Output. The NRE happens when I try to add anything through intellisense. Nothing from Tailwind shows in the intellisense; only the Bootstrap, and static stuff.

Thanks for the bug report! It appears that I forgot to add a null check in the code. I've updated the extension, so it should be fixed now.

1.1.7.5 has not fixed this issue. It's made no difference. Still get NREs in .razor files. The entire extension is rendered unusable, and needs to be disabled, to be able to code. I'm not sure what other metrics I can give to help troubleshoot, and I'm working on closed-source code, so I can't share repos.

I’m really sorry about that. Just a quick question (if you could answer it), do you have any theme configuration in your tailwind.config.js? Also, I can try to add null checks wherever I can, but I can’t really reproduce this issue so that’s the best I can do.

That much, I can share:

module.exports = {
    content: [
        "**/*.{cshtml,cshtml.cs,css,html,js,jsx,razor,razor.cs,ts,tsx}"
    ],
    theme: {
        extend: {

            colors: {
                "brand-blue": {
                    DEFAULT: "#0f1654",
                    "50": "#e7e8ee",
                    "100": "#cfd0dd",
                    "200": "#9fa2bb",
                    "300": "#6f7398",
                    "400": "#3f4576",
                    "500": "#0f1654",
                    "600": "#0c1243",
                    "700": "#090d32",
                    "800": "#060922",
                    "900": "#030411",
                    "950": "#020202"
                },
                "brand-orange": {
                    DEFAULT: "#ff7c22",
                    "50": "#fff2e9",
                    "100": "#ffe5d3",
                    "200": "#ffcba7",
                    "300": "#ffb07a",
                    "400": "#ff964e",
                    "500": "#ff7c22",
                    "600": "#cc631b",
                    "700": "#994a14",
                    "800": "#66320e",
                    "900": "#331907",
                    "950": "#220804"
                },
            },

            boxShadow: {
                shell: [
                    "2.0px 2.0px 2.0px rgba(0,0,0,0.18)",
                    "0.0px 2.0px 0.0px rgba(0,0,0,0.18)"
                ],
            },

        }
    },
    plugins: [],
};

I don't have much time atm to look at this properly. When I'm able to, I'll attach dnSpy, and run through the whole process with it, and see where it crashes.

I have been able to uncover another user-centric bug though, which may be worth noting in the docs... or explicitly countering in the extension.

With the content string set as "**/*.{cshtml,cshtml.cs,css,html,js,jsx,razor,razor.cs,ts,tsx}", this will also track the node_modules folder (with default settings, without specifying a location). In Blazor/MVC, you have trackable files at the root level, and mulitple folders from the root level as well (not to mention separate assemblies... but that's a whole other barrel of pain!). Because I was tracking node_modules, I got this in my build output, when building Tailwind. It was also taking 10+ seconds to build.

warn - The utility `w-[calc(100%-theme('spacing[some_key][1.5]'))]` contains an invalid theme value and was not generated.

The fix for this would be to split static content from managed content, something like this:

    content: [
        "wwwroot/**/*.{css,js}", ,
        "ReactApps/**/*.{css,scss,js,jsx,ts,tsx}",
        "**/*.{cshtml,cshtml.cs,html,razor,razor.cs}"
    ],

And you would expect this to work fine. But, I get following exception, when the project is first loaded (and the same NREs).

SetSite failed for package [TailwindCSSIntellisensePackage]
Source: 'mscorlib' 
Description: The given key was not present in the dictionary.
System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
   at System.ThrowHelper.ThrowKeyNotFoundException()
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Linq.Enumerable.Count[TSource](IEnumerable`1 source)
   at TailwindCSSIntellisense.Configuration.CompletionConfiguration.LoadIndividualConfigurationExtend(TailwindConfiguration config)
   at TailwindCSSIntellisense.Configuration.CompletionConfiguration.<ReloadCustomAttributesAsync>d__35.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at TailwindCSSIntellisense.Configuration.ConfigurationFileReloader.<InitializeAsync>d__11.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at TailwindCSSIntellisense.TailwindCSSIntellisensePackage.<InitializeAsync>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.VisualStudio.Shell.AsyncPackage.<>c__DisplayClass21_0.<<Microsoft-VisualStudio-Shell-Interop-IAsyncLoadablePackageInitialize-Initialize>b__1>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.VisualStudio.Services.VsTask.RethrowException(AggregateException e)
   at Microsoft.VisualStudio.Services.VsTask.InternalGetResult(Boolean ignoreUIThreadCheck)

However, even just using "**/*.razor" still gives the NREs.

Yep, thanks. I also got the KeyNotFoundException error. I found that the error occurs when the extension tries to load custom descriptions for certain custom classes (boxShadow happens to be one of them), and I am working on a fix.

I've found the issue.

The NRE happens here: https://github.com/theron-wang/VS2022-Editor-Support-for-Tailwind-CSS/blob/main/src/Completions/Controllers/RazorCompletionController.cs#L220

_currentSession.SelectedCompletionSet.Filter();

_currentSession is guarded, SelectedCompletionSet is not.

I've added the extra guard clause in, and recompiled with dnSpy, and it fixes the NRE... however, completions aren't running for .razor files, it seems.

Yep, I found that too. There was also another part of the code which tried to access non-existent keys in a dictionary, which is why the completions didn’t show up. Thanks a ton for your help!

I don’t have time right now, but I will update the extension as soon as I get the chance.

Firstly, thanks for creating this extension!

Now for the bug.
It seems that even in projects that are not using tailwind, the extension seems to throw the same error.
image

Extension Version: 1.1.75
Steps to reproduce:

  1. Create a new Blazor project. (any: WASM/Server)
  2. Add an element and class attribute start typing and deleting with backspace.

@Abi-Rai This should be fixed in the latest update. (I also fixed Tailwind completions showing up in non-Tailwind projects, so thank you for letting me know about that!)

Thanks!

@theron-wang
For Non-tailwind projects, the latest update has fixed the error when typing and deleting the text in the class attribute however, pressing tab/enter to select suggestions throws the Object ref null error. Clicking the suggestion does not throw the error.

Extension Version: 1.1.7.6

@Abi-Rai could you refer to #14 and see my response? Thanks.