Tag Archives: Secrets

Debugging an Asp.Net Core React Application in Azure

I’ve recently been working with an Asp.Net Core ReactJS application. When trying to debug this remotely, I switched on Development mode in order to get a stack trace when it crashed:

Instead of the stack trace, I got this:

An unhandled exception occurred while processing the request. AggregateException: One or more errors occurred. (One or more errors occurred. (The NPM script ‘start’ exited without indicating that the create-react-app server was listening for requests. The error output was: )) System.Threading.Tasks.Task.ThrowIfExceptional(bool includeTaskCanceledExceptions)
InvalidOperationException: The NPM script ‘start’ exited without indicating that the create-react-app server was listening for requests. The error output was:

This is, in fact, caused by the following code:

            app.UseSpa(spa =>
            {
                spa.Options.SourcePath = "ClientApp";

                if (_env.IsDevelopment())
                {
                    spa.UseReactDevelopmentServer(npmScript: "start");
                }
            });

This uses the setting “Development” to determine whether to start a local React server; which will fail on a remote server. However, I want to see a stack trace, which is here:

            if (_env.IsDevelopment())            
            {
                app.UseDeveloperExceptionPage();
            }

The problem here is that “Development” has two functions – it displays a stack trace, and it manages all these variables that should only run on your machine. What we need are two settings that both mean “Development”; one that means that we’re running locally, and one that we’re trying to debug. Start with an environment variable:

You can set this to anything you choose… But I’ve gone with “LocalDevelopment”.

The next step is to find all the places that check IsDevelopment, and replace them. What we essentially want is this:

                //if (_env.IsDevelopment())
                if (_env.IsEnvironment("LocalDevelopment"))
                {

However, we can create our own extension method, so that the code looks a lot neater:

        public static bool IsLocalDevelopment(this IWebHostEnvironment env)
        {
            return (env.IsEnvironment("LocalDevelopment"));
        }

Remember that IsEnvironment() is actually an extension method itself, so you would need to include:

using Microsoft.Extensions.Hosting;

In your extension class.

What to change

The following places will, at a minimum, need replacing for a standard web app. The stack trace should be displayed in either situation:

        public void Configure(IApplicationBuilder app)
        {
            if (_env.IsDevelopment() || _env.IsLocalDevelopment())                  
            {
                app.UseDeveloperExceptionPage();
            }

The React check that started all this:

            app.UseSpa(spa =>
            {
                spa.Options.SourcePath = "ClientApp";

                if (_env.IsLocalDevelopment())
                {
                    spa.UseReactDevelopmentServer(npmScript: "start");
                }
            });

Also, if you’re using local secrets, you’ll need this in Program.cs:

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder
                        .ConfigureAppConfiguration((hostingContext, config) =>
                        {
                            if (hostingContext.HostingEnvironment.IsEnvironment("LocalDevelopment"))
                            {
                                config.AddUserSecrets<Program>();
                            }

Because, by default, local secrets are only added for Development only.

Summary

That’s it, you can now set the ASPNETCORE_ENVIRONMENT to Development on a remote server, and you should get a stack trace.

GitHub Secrets

I’ve recently been playing around with GitHub Actions. The reason being that I created this little NuGet package, because I needed such a utility for a web site that I’m working on.

I’ll go into how I set-up a basic CI/CD pipeline in a later post; but after playing with GitHub actions for a short period of time, it because clear that the first thing you need to understand is how secrets work. Otherwise you may, for example, generate a GitHub API key, and check that into your source control; and then get a rather harshly worded e-mail from GitHub telling you to stop doing that.

It turns out that storing secrets in GitHub is very easy. First, visit your repository; and, under the Settings tab, you’ll find Secrets:

Here, you just select Add Secret. Give the secret a name and tell it what the secret is:

Finally, to use your secret inside a workflow, you use the following format:

${{secrets.SECRET_NAME}}

References

https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets