question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Blazor HotReload throws `System.NullReferenceException` when using Serilog

See original GitHub issue

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

When using the serilog browser-console sink, the application throws System.NullReferenceException. The author of the library already tried to fix it but it looks like it’s a problem with Blazor itself. Here is a reference to the issue in the browser-console sink repository https://github.com/serilog/serilog-sinks-browserconsole/issues/20

Expected Behavior

We should be able to add a log and start the application without getting a null reference exception.

Steps To Reproduce

  1. Create a new Blazor project.
  2. Add serilog browser-console sink package.
  3. Update the entry point so it looks like this:
// This is the line that makes Blazor throw the exception
Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Debug()
    .WriteTo.BrowserConsole(
        restrictedToMinimumLevel: LogEventLevel.Information,
        outputTemplate: "[{Level:u3}] {Message:lj}{NewLine}{Exception}", 
        CultureInfo.InvariantCulture)
    .CreateLogger();

try
{
    WebAssemblyHostBuilder builder = WebAssemblyHostBuilder.CreateDefault(args);
    builder.RootComponents.Add<App>(selector: "#app");
    builder.RootComponents.Add<HeadOutlet>(selector: "head::after");

    builder.Logging.AddSerilog();

    builder.Services.AddServices();

    WebAssemblyHost app = builder.Build();
    await app.RunAsync();
}
catch (Exception ex)
{
    Log.Fatal(ex, messageTemplate: "An exception occurred while creating the WASM host");
    throw;
}

Exceptions (if any)

[ FTL ] An exception occurred while creating the WASM host System.NullReferenceException: Object reference not set to an instance of an object. at Microsoft.AspNetCore.Components.WebAssembly.HotReload.WebAssemblyHotReload.InitializeAsync() at Microsoft.AspNetCore.Components.WebAssembly.Hosting.WebAssemblyHost.RunAsyncCore(CancellationToken cancellationToken, WebAssemblyCultureProvider cultureProvider) at Program.<Main>$(String[] args) in D:\workspace\projects\Hephaestus\src\presentation\Hephaestus.WebApp\Program.cs:line 43 (anonymous) @ blazor.webassembly.js:1 beginInvokeJSFromDotNet @ blazor.webassembly.js:1 Gt @ blazor.webassembly.js:1 Ii @ dotnet.7.0.0.k4xetpuqcq.js:5 _mono_wasm_invoke_js_blazor @ dotnet.7.0.0.k4xetpuqcq.js:14 $func313 @ 009924a6:0x1d4a3 $func283 @ 009924a6:0x1c8d1 $func221 @ 009924a6:0xdfdd $func220 @ 009924a6:0xce8f $func8112 @ 009924a6:0x1a1fcc $func2053 @ 009924a6:0x859fe $func2058 @ 009924a6:0x86066 $func2085 @ 009924a6:0x88125 $mono_wasm_invoke_method_ref @ 009924a6:0x9bcb Module._mono_wasm_invoke_method_ref @ dotnet.7.0.0.k4xetpuqcq.js:14 _Microsoft_AspNetCore_Components_WebAssembly__Microsoft_AspNetCore_Components_WebAssembly_Services_DefaultWebAssemblyJSRuntime_EndInvokeJS @ _Microsoft_AspNetCore_Components_WebAssembly__Microsoft_AspNetCore_Components_WebAssembly_Services_DefaultWebAssemblyJSRuntime_EndInvokeJS:26 endInvokeJSFromDotNet @ blazor.webassembly.js:1 (anonymous) @ blazor.webassembly.js:1 Promise.then (async) beginInvokeJSFromDotNet @ blazor.webassembly.js:1 Gt @ blazor.webassembly.js:1 Ii @ dotnet.7.0.0.k4xetpuqcq.js:5 _mono_wasm_invoke_js_blazor @ dotnet.7.0.0.k4xetpuqcq.js:14 $func313 @ 009924a6:0x1d4a3 $func283 @ 009924a6:0x1c8d1 $func221 @ 009924a6:0xdfdd $func220 @ 009924a6:0xce8f $func8112 @ 009924a6:0x1a1fcc $func2053 @ 009924a6:0x859fe $func2051 @ 009924a6:0x85974 $func1394 @ 009924a6:0x68446 $func313 @ 009924a6:0x1d45c $func283 @ 009924a6:0x1c8d1 $func221 @ 009924a6:0xdfdd $func220 @ 009924a6:0xce8f $func8112 @ 009924a6:0x1a1fcc $func2053 @ 009924a6:0x859fe $func2058 @ 009924a6:0x86066 $func2085 @ 009924a6:0x88125 $mono_wasm_invoke_method_ref @ 009924a6:0x9bcb Module._mono_wasm_invoke_method_ref @ dotnet.7.0.0.k4xetpuqcq.js:14 _Hephaestus_WebApp__entrypoint @ _Hephaestus_WebApp__entrypoint:26 (anonymous) @ dotnet.7.0.0.k4xetpuqcq.js:5 ji @ dotnet.7.0.0.k4xetpuqcq.js:5 callEntryPoint @ blazor.webassembly.js:1 Vt @ blazor.webassembly.js:1 await in Vt (async) (anonymous) @ blazor.webassembly.js:1 (anonymous) @ blazor.webassembly.js:1 blazor.webassembly.js:1

   System.AggregateException: One or more errors occurred. (Object reference not set to an instance of an object.)

—> System.NullReferenceException: Object reference not set to an instance of an object. at Microsoft.AspNetCore.Components.WebAssembly.HotReload.WebAssemblyHotReload.InitializeAsync() at Microsoft.AspNetCore.Components.WebAssembly.Hosting.WebAssemblyHost.RunAsyncCore(CancellationToken cancellationToken, WebAssemblyCultureProvider cultureProvider) at Program.<Main>$(String[] args) in D:\workspace\projects\Hephaestus\src\presentation\Hephaestus.WebApp\Program.cs:line 48 — End of inner exception stack trace —

.NET Version

net7.0

Anything else?

No response

Issue Analytics

  • State:closed
  • Created 9 months ago
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
wtorricoscommented, Dec 14, 2022

The workout around works like a charm, thank you for the investigation @MackinnonBuck! I also added an update in the original issue in the browser console repo. I’m not sure if you are going to track the next steps in the same ticket, at least from my side the issue is resolved and can be closed.

1reaction
MackinnonBuckcommented, Dec 14, 2022

Summary

The root of the problem is that Serilog.Sinks.BrowserConsole creates and uses its own IJSRuntime instance (from its own implementation) when one isn’t provided to LoggerConfigurationBrowserConsoleExtensions.BrowserConsole().

Details

Since the IJSRuntime instance created by Serilog is different from the IJSRuntime used by Blazor, it will have its own state tracking pending JS invocations, DotNetObjectReference instances, etc.

The JSRuntime base implementation tracks pending JS invocations using a long ID that increments for each JS interop call. In this particular case, the invocation IDs between the two JSRuntime instances conflict and cause the crash:

  1. Using its own JSRuntime, Serilog kicks off its first two interop calls to console.info with IDs 2 and 3 respectively.
  2. Blazor uses its JSRuntime instance to asynchronously invoke a dynamic import for the blazor-hotreload.js module, intending to store the result as an IJSObjectReference. This invocation has an ID of 2.
  3. Serilog’s first two JS invocations complete. The ID 2 invocation gets incorrectly interpreted as being the completion of Blazor’s import() call. The return value can’t be deserialized into an IJSObjectReference, so it becomes null on the .NET side, causing the NullReferenceException.

Workaround

This can be worked around by passing the IJSRuntime from app.Services into the call to LoggerConfigurationBrowserConsoleExtensions.BrowserConsole().

Next steps

Ultimately, the specific issue at hand is a Serilog bug. From Blazor’s perspective, all bets are off as soon as a library interferes with its internal state in a manner other than through the public API. That said, we could look into adding extra checks to catch this case rather than failing silently.

Read more comments on GitHub >

github_iconTop Results From Across the Web

hot reload - Blazor wasm HotReload General Exception
Unhandled Exception: blazor.webassembly.js:1 System.NullReferenceException: Object reference not set to an instance of an object.
Read more >
Handle errors in ASP.NET Core Blazor apps
Rendering logic can throw an exception. An example of this scenario occurs when @someObject. PropertyName is evaluated but @someObject is null ...
Read more >
C# 11 and . NET 7 - Modern Cross-Platform Development ...
Chapter 16: Building User Interfaces Using Blazor ... Hot reloading using Visual Studio Code and the command line • 172.
Read more >
An Atypical ASP.NET Core 6 Design Patterns Guide
That is true whether you are designing a small component or a whole system. However, be careful: throwing patterns into the mix just...
Read more >
How to implement Serilog in Blazor WebAssembly project
First of all - you need to decide where the logs need to go. What I mean is - when you log in...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found