NT.Blazor.ErrorBoundary.AspNetCore
2.0.0
dotnet add package NT.Blazor.ErrorBoundary.AspNetCore --version 2.0.0
NuGet\Install-Package NT.Blazor.ErrorBoundary.AspNetCore -Version 2.0.0
<PackageReference Include="NT.Blazor.ErrorBoundary.AspNetCore" Version="2.0.0" />
<PackageVersion Include="NT.Blazor.ErrorBoundary.AspNetCore" Version="2.0.0" />
<PackageReference Include="NT.Blazor.ErrorBoundary.AspNetCore" />
paket add NT.Blazor.ErrorBoundary.AspNetCore --version 2.0.0
#r "nuget: NT.Blazor.ErrorBoundary.AspNetCore, 2.0.0"
#:package NT.Blazor.ErrorBoundary.AspNetCore@2.0.0
#addin nuget:?package=NT.Blazor.ErrorBoundary.AspNetCore&version=2.0.0
#tool nuget:?package=NT.Blazor.ErrorBoundary.AspNetCore&version=2.0.0
NT.Blazor.ErrorBoundary
Reusable Blazor error-boundary reporting with a WebAssembly-safe core package, an ASP.NET Core logging integration, and an optional Application Insights add-on. The component renders generic fallback UI by default and reports failures through ILogger or a configurable HTTP endpoint. The core and ASP.NET Core packages don't depend on Application Insights or the OpenTelemetry SDK; only the optional NT.Blazor.ErrorBoundary.AzureMonitor add-on does.
Packages
| Package | Use it for |
|---|---|
NT.Blazor.ErrorBoundary |
The NTErrorBoundary component, shared reporting contracts, and HTTP reporting from Blazor WebAssembly. |
NT.Blazor.ErrorBoundary.AspNetCore |
Direct server-side exception logging and an ASP.NET Core endpoint that receives WebAssembly error reports. |
NT.Blazor.ErrorBoundary.AzureMonitor |
Optional. Sends every error and event to Application Insights directly, as native exceptions the Failures view groups and as custom events, unaffected by trace sampling. See Why the add-on. |
All packages target .NET 10 and .NET 11. The ASP.NET Core package depends on the core package, so installing it in a server project provides both. Install the core package directly in a separate .Client or standalone WebAssembly project.
# Server or API project
dotnet add package NT.Blazor.ErrorBoundary.AspNetCore
# Separate .Client or standalone WebAssembly project
dotnet add package NT.Blazor.ErrorBoundary
Choose the setup for your render mode
| Render mode | Server project | Client project |
|---|---|---|
| Interactive Server | Register server logging. The HTTP endpoint is optional. | Not applicable. |
| Interactive WebAssembly | Register server logging and map the telemetry endpoint. | Register the HTTP reporter. |
| Interactive Auto | Register server logging and map the telemetry endpoint. | Register the HTTP reporter so the same boundary continues working after WebAssembly activation. |
| Standalone WebAssembly | The separate ASP.NET Core API registers server logging and maps the endpoint. | Register the HTTP reporter with the API URI. |
Upgrading from 1.x
Version 2.0.0 changes target frameworks, log field names, and some defaults. Work through this list before deploying.
.NET 9 is no longer supported. All packages target .NET 10 and .NET 11.
The ASP.NET Core package has a new dependency,
OpenTelemetry.Api.ProviderBuilderExtensions1.15.3 or later. It registers this package's meter and activity source with the host's OpenTelemetry pipeline, and does not pull in the OpenTelemetry SDK.Obsolete names now warn.
AddBlazorErrorBoundaryServerLoggingandMapBlazorErrorBoundaryTelemetrystill work but raiseCS0618, which fails builds that treat warnings as errors. UseAddNTBlazorErrorBoundaryServerLoggingandMapNTBlazorErrorBoundaryTelemetry.Server log fields moved from logging scopes to attributes on the log entry, and were renamed. Update Application Insights queries, workbooks, and alerts. For example,
customDimensions.BlazorBoundaryNamebecomescustomDimensions['blazor.boundary.name']. The log message templates also use the new names as placeholders, such as{blazor.report.kind}in place of{ReportKind}and{blazor.boundary.name}in place of{BoundaryName}. Version 1.x wrote only the first five fields in the table for server-rendered errors; the rest applied to browser reports only.1.x scope key 2.0.0 attribute BlazorBoundaryNameblazor.boundary.nameBlazorIsInteractiveblazor.interactiveBlazorOriginUriblazor.navigation.origin_urlBlazorRenderModeblazor.render_modeBlazorUriurl.fullBlazorBreadcrumbsblazor.navigation.breadcrumbsApplicationVersionblazor.app.versionBlazorClientSessionIdsession.idandmicrosoft.session.idBlazorExceptionDetailsblazor.exception.detailsBlazorExceptionMessageblazor.exception.messageBlazorExceptionStackTraceblazor.exception.stacktraceBlazorExceptionTypeblazor.exception.typeBlazorIsNavigationInterceptedblazor.navigation.interceptedBlazorIsOnlineblazor.client.onlineBlazorJavaScriptColumncode.column.numberBlazorJavaScriptLinecode.line.numberBlazorJavaScriptSourcecode.file.pathBlazorNavigationIdblazor.navigation.idBlazorNavigationPhaseblazor.navigation.phaseBlazorOccurredAtUtcblazor.error.occurred_atBlazorReportKindblazor.report.kindBlazorTargetUriblazor.navigation.target_urlUserAgentuser_agent.originalUserIduser.idandenduser.idRequestId,RequestMethod,RequestPathNo replacement. ASP.NET Core's own request logs and traces carry them. TraceId,SpanIdNo replacement. The log entry's trace context carries them. The new attributes
blazor.error.fingerprint,blazor.error.reference_id, andblazor.page.traceparenthave no 1.x equivalent. See Log fields.NavigationStalledreports are logged as events without an exception. They no longer appear in theexceptionstable. QuerycustomEventsforblazor.navigation.stalledinstead.Browser exceptions are logged as
NT.Blazor.ErrorBoundary.AspNetCore.ClientBlazorErrorReportException. In 1.x this was a nested type of the extensions class. ItsMessageis now the browser's original message, so Application Insights problem IDs for browser errors change.The fallback markup changed. The heading is a
divwithrole="heading"and anaria-levelinstead of anh2, the details class isnt-blazor-error-detailsinstead ofnt-blazor-error-boundary__details, and a reference line is shown. Update any CSS or tests that depend on the old markup.The telemetry endpoint validates reports. It rejects unknown report kinds and out-of-range timestamps with
400, and request bodies overMaxReportRequestByteswith413.Some defaults now report or recover more.
NTErrorBoundary.RecoverOnNavigationistrue. Set it tofalseto keep the previous behavior.NTBlazorErrorBoundaryHttpClientOptions.ReportUnhandledExceptionsistrue, so WebAssembly clients report exceptions that occur outside any boundary. Expect more reports.- Blazor Server circuit connection down and up events are logged.
- Query strings and fragments are removed from reported URLs.
NTBlazorErrorReportis a record. It has value equality and supportswith. ItsToString()prints only the kind, exception type, and reference ID.
Complete error-boundary setup for a Blazor Web App
This is the typical setup for a Blazor Web App that uses Interactive Server, Interactive WebAssembly, or Interactive Auto render modes.
1. Configure the server project
Install NT.Blazor.ErrorBoundary.AspNetCore in the server project, then register the server reporter before building the application. The report path is host-owned and can be changed to match the application's API conventions.
using NT.Blazor.ErrorBoundary.AspNetCore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents()
.AddInteractiveWebAssemblyComponents();
builder.Services.AddNTBlazorErrorBoundaryServerLogging("/api/blazor-errors");
var app = builder.Build();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode()
.AddInteractiveWebAssemblyRenderMode();
app.MapNTBlazorErrorBoundaryTelemetry();
app.Run();
AddNTBlazorErrorBoundaryServerLogging does the following:
- It registers
NTBlazorServerErrorReporteras the scopedINTBlazorErrorReporterused during server rendering. - It stores the report path used by
MapNTBlazorErrorBoundaryTelemetryandNTBlazorErrorBoundaryScript. - It reads
IHostEnvironmentso exception details are rendered by default only in Development. - It registers a circuit handler that logs Blazor Server connection down and connection up events with
aspnetcore.components.circuit.id, and adds that ID to server-rendered error logs. Circuit opens and closes are not logged; ASP.NET Core'saspnetcore.components.circuit.activeandaspnetcore.components.circuit.durationmetrics cover them (see Blazor's built-in telemetry). - It registers this package's meter and activity source with the host's OpenTelemetry pipeline, if the host configures one.
MapNTBlazorErrorBoundaryTelemetry maps a JSON POST endpoint at the configured path. Accepted reports return 204 No Content and are written through ILogger. Invalid reports return 400, and oversized requests return 413 (see Securing the telemetry endpoint).
The previous names AddBlazorErrorBoundaryServerLogging and MapBlazorErrorBoundaryTelemetry still work but are obsolete.
If the application never uses a WebAssembly render mode, calling MapNTBlazorErrorBoundaryTelemetry is optional. Server-side exceptions are logged directly and do not make an HTTP round trip.
2. Configure the .Client project
Install NT.Blazor.ErrorBoundary in the client project and register the HTTP reporter in its Program.cs.
using Microsoft.Extensions.DependencyInjection;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Services
.AddNTBlazorErrorBoundaryHttpClient("/api/blazor-errors", builder.HostEnvironment.Environment)
.ConfigureHttpClient(client => {
client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress);
});
await builder.Build().RunAsync();
The base address is required when reportUri is relative. An absolute report URI can be used instead, in which case the reporter does not require BaseAddress.
The environment name controls the default exception-detail behavior in the browser. Pass builder.HostEnvironment.Environment so DevelopmentOnly behaves consistently between the server and client DI containers.
For cross-origin APIs, use an absolute endpoint URI and configure CORS on the API host. If the endpoint requires authentication, configure the returned IHttpClientBuilder with the application's authorization message handler.
The reporter sends each report with this HttpClient, so any authorization handler applies. Reports up to 64,000 bytes are sent with the browser's keepalive fetch option, so an upload still in flight when the page navigates away is finished by the browser instead of lost; the browser script does the same for its own uploads. Browsers refuse keepalive for larger bodies, so larger reports are sent without it. If the request fails with a network error, 5xx, 408, or 429, the report is handed to the browser script's retry queue, which resends it on the next page load, when connectivity returns, or with a page-hide beacon. Other 4xx responses mean the server rejected the report, and it is not retried.
The client registration also reports unhandled exceptions that occur outside any NTErrorBoundary, such as exceptions from components that no boundary wraps, which Blazor otherwise only shows as its "An unhandled error has occurred" bar. They are reported with the Blazor log category as the boundary name. Set NTBlazorErrorBoundaryHttpClientOptions.ReportUnhandledExceptions to false to turn this off.
3. Load browser telemetry
Add the script component before blazor.web.js in App.razor:
@using NT.Blazor.ErrorBoundary.Components
<NTBlazorErrorBoundaryScript StallTimeoutMs="15000" />
<script src="@Assets["_framework/blazor.web.js"]" defer></script>
NTBlazorErrorBoundaryScript renders the package's fingerprinted <script> tag with the report URI registered by AddNTBlazorErrorBoundaryServerLogging, so the path is configured in one place on the server. It also writes the current request's W3C traceparent into the tag so browser reports correlate with the server request that rendered the page. StallTimeoutMs is optional and defaults to 15 seconds. The tag also carries the server app's version, which reports the browser script raises, such as JavaScript errors and stalled navigations, are sent with.
To load the script by hand instead, use data-report-uri (required), data-application-version, data-stall-timeout-ms, and data-traceparent on a <script src="@Assets["_content/NT.Blazor.ErrorBoundary/nt-blazor-error-boundary.js"]"> tag. The script doesn't initialize when data-report-uri is absent.
Browser telemetry:
- Adds browser and navigation context to boundary reports.
- Captures JavaScript errors and unhandled promise rejections.
- Reports Blazor framework files (
_framework/*,blazor.*.js) that fail to load, for example after a deployment replaces them. Other failed resources, such as images, are ignored. - Reports Blazor Server reconnection that fails, fails to resume, or is rejected. With a custom reconnect UI (the
#components-reconnect-modalelement, as in the .NET 10 Blazor Web App template), all three states are detected. With the framework's built-in reconnect UI, failure is detected from its status text; on rejection the built-in UI reloads the page, so there is nothing to report. - Stores up to 20 recent navigation breadcrumbs in
sessionStorage. - Gives every report a reference ID, and sends the page's
traceparentas a request header and report field. - Drops a report that repeats an earlier one (same kind, exception type, message, boundary, and source location) within 5 seconds of its last occurrence. Every repeat restarts the window, so a crash loop is sent once and stays suppressed until it pauses for 5 seconds. This keeps it from flooding the endpoint.
- Queues failed report submissions and retries them when connectivity returns. Reports the server rejects with a
4xxother than408or429are not retried. - Remembers the reference IDs of the last 10 delivered reports for the browser session, so a report is never sent twice. This covers an upload still in flight when the page navigates away: the browser completes it, but the page sees it fail, and without this the next page would resend it. A page entering the back-forward cache may come back, so its uploads are left to settle normally instead.
- Uses keepalive requests and a page-hide beacon when available.
- Never interrupts application behavior when telemetry storage or delivery fails.
Reports raised by the browser script itself use the browser's fetch with same-origin credentials, so cookie authentication applies but an HttpClient authorization handler does not. Allow browser reports through the endpoint's authorization policy, or use cookie authentication, if you want JavaScript errors, stalls, and load failures.
4. Add the boundary to the component tree
Place NTErrorBoundary around the part of the component tree that should fail and recover together. Wrapping the layout body is a common application-wide boundary.
@using NT.Blazor.ErrorBoundary.Components
@inherits LayoutComponentBase
<NTErrorBoundary>
@Body
</NTErrorBoundary>
You can instead wrap Routes, a page, or a smaller feature. Smaller boundaries isolate failures so the rest of the page remains usable.
Give a boundary a Name to tell its errors apart. The name is logged as blazor.boundary.name and tags the blazor.errors metric:
<NTErrorBoundary Name="Checkout">
<CheckoutForm />
</NTErrorBoundary>
When a descendant throws, the default fallback:
- Displays a generic message.
- Displays a short reference ID, such as
Reference: 7F3K2QAB. The same ID is logged asblazor.error.reference_id, so support can find the exact report a user saw. - Hides exception details unless they are explicitly enabled or the environment is Development.
- Displays a Try again button for interactive rendering.
- Displays a Reload page link for static rendering.
- Attempts to report the error without allowing reporting failures to replace the fallback UI.
The boundary also clears its error when the user navigates, so a boundary around the layout body doesn't keep showing the fallback on the next page. Set RecoverOnNavigation="false" to keep the error until Try again.
The default fallback's scoped styles ship in the package's CSS bundle, which the host loads through its {AssemblyName}.styles.css link included by the Blazor Web App template.
Fallback text and theming
Every fallback string is a parameter, so apps can pass localized text, for example from IStringLocalizer:
<NTErrorBoundary Title="@L["ErrorTitle"]"
Message="@L["ErrorMessage"]"
ReferenceLabel="@L["Reference"]"
RetryText="@L["TryAgain"]"
ReloadText="@L["ReloadPage"]"
HeadingLevel="3">
@Body
</NTErrorBoundary>
HeadingLevel (1–6, default 2) sets the title's aria-level, so the fallback fits the page's heading structure.
The fallback reads these CSS custom properties and falls back to the defaults below when they are unset. Set them on any ancestor in the app's own stylesheet, for example :root { --nt-error-boundary-accent: #0b57d0; }:
| Property | Default |
|---|---|
--nt-error-boundary-accent |
#b42318 |
--nt-error-boundary-background |
#fff4f4 |
--nt-error-boundary-color |
#5f1414 |
--nt-error-boundary-button-color |
#ffffff |
--nt-error-boundary-radius |
0 |
--nt-error-boundary-spacing |
0.5rem |
Its elements use the classes nt-blazor-error-boundary, nt-blazor-error-title, nt-blazor-error-message, nt-blazor-error-reference, and nt-blazor-error-details.
Interactive Server-only setup
For an application that never activates WebAssembly, only the server registration and component are required.
builder.Services.AddNTBlazorErrorBoundaryServerLogging("/api/blazor-errors");
@using NT.Blazor.ErrorBoundary.Components
<NTErrorBoundary>
@Body
</NTErrorBoundary>
The path must be supplied because it is part of the shared options contract, but the endpoint does not need to be mapped when no browser-side reports will be posted.
Standalone WebAssembly with a separate API
Configure the ASP.NET Core API exactly like the server portion of the complete setup:
builder.Services.AddNTBlazorErrorBoundaryServerLogging("/api/blazor-errors");
var app = builder.Build();
app.MapNTBlazorErrorBoundaryTelemetry();
Configure the standalone WebAssembly application with the API's absolute URI:
builder.Services.AddNTBlazorErrorBoundaryHttpClient(
"https://api.example.com/api/blazor-errors",
builder.HostEnvironment.Environment);
The API host must explicitly allow the WebAssembly application's origin through CORS.
Exception-detail policy
RenderExceptionDetails controls what the default fallback renders:
@using NT.Blazor.ErrorBoundary.Components
<NTErrorBoundary RenderExceptionDetails="ExceptionDetailsMode.Never">
@Body
</NTErrorBoundary>
| Value | Behavior |
|---|---|
DevelopmentOnly |
Default. Render details only when the registered environment is Development. |
Always |
Always render exception details. Use cautiously because messages and stack traces can contain sensitive information. |
Never |
Never render exception details. |
The rendering policy affects only the fallback UI. Reports and server logs still contain diagnostic exception fields.
Custom fallback content
Supply FallbackContent to replace the package's default fallback UI. Its context is an NTErrorBoundaryFailure with the Exception and the ReferenceId:
@using NT.Blazor.ErrorBoundary.Components
<NTErrorBoundary>
<ChildContent>
@Body
</ChildContent>
<FallbackContent Context="failure">
<section role="alert">
This section is temporarily unavailable. Reference: @failure.ReferenceId
</section>
</FallbackContent>
</NTErrorBoundary>
Blazor's inherited ErrorContent parameter also still works, but it receives only the exception. When both are set, FallbackContent wins.
The exception is still reported before the custom fallback renders. Avoid displaying exception.Message outside a trusted development environment.
Custom reporters
NTErrorBoundary reports through whichever INTBlazorErrorReporter is registered. AddNTBlazorErrorBoundaryServerLogging registers one that logs on the server, and AddNTBlazorErrorBoundaryHttpClient registers one that posts to the endpoint. To send errors somewhere else, register your own implementation after the built-in call; the last registration wins.
Replace the reporter only to change where errors go. Your reporter then takes over everything the built-in one does:
- Server: the log entry and its fields (including
blazor.error.fingerprintand the circuit ID), theblazor.errorsmetric, and the call toINTBlazorErrorBoundaryExporter. - Client: the HTTP upload,
keepalive, the browser retry queue, and the browser navigation context. - Both:
FilterReportandMaxReportFieldLength, which only the built-in reporters apply.
The registration calls still do their other work: the report path, the exception-detail environment, the circuit handler, and, on the client, forwarding of exceptions that no boundary catches. To send errors to a second destination and keep the log, register an INTBlazorErrorBoundaryExporter instead. To redact or drop reports, use FilterReport.
ReportAsync receives the exception and an NTBlazorErrorBoundaryContext:
BoundaryName: the boundary'sName, or its type name.ReferenceId: the reference the fallback shows.IsInteractiveandRenderMode: how the boundary rendered.Uri: the current page URL.OriginUri: the URL when the boundary was created.
Exceptions forwarded from outside any boundary carry only BoundaryName, which is then the Blazor log category, and ReferenceId. The boundary does not wait for ReportAsync before it shows the fallback. If ReportAsync throws, the boundary logs a warning, and the fallback is unaffected.
NTBlazorErrorReport.FromException builds the same report the built-in reporters send. It sets the app version, removes query strings and fragments from URLs, and truncates string fields. Apply FilterReport yourself to keep honoring it:
using Microsoft.Extensions.Options;
using NT.Blazor.ErrorBoundary.Models;
using NT.Blazor.ErrorBoundary.Services;
// IErrorQueue stands for the application's own transport.
public sealed class QueueErrorReporter(IErrorQueue _queue, IOptions<NTBlazorErrorBoundaryHttpClientOptions> _options) : INTBlazorErrorReporter {
public async Task ReportAsync(Exception exception, NTBlazorErrorBoundaryContext context, CancellationToken cancellationToken = default) {
var options = _options.Value;
var report = NTBlazorErrorReport.FromException(exception, context, options.MaxReportFieldLength);
if ((options.FilterReport is null ? report : options.FilterReport(report)) is { } filtered) {
await _queue.SendAsync(filtered, cancellationToken);
}
}
}
// Server project
builder.Services.AddNTBlazorErrorBoundaryServerLogging("/api/blazor-errors");
builder.Services.AddScoped<INTBlazorErrorReporter, QueueErrorReporter>();
// .Client or standalone WebAssembly project
builder.Services.AddNTBlazorErrorBoundaryHttpClient("/api/blazor-errors", builder.HostEnvironment.Environment);
builder.Services.AddScoped<INTBlazorErrorReporter, QueueErrorReporter>();
To use the boundary with no built-in registration, for example in Blazor Hybrid, register only your reporter. Then set NTErrorBoundaryOptions.IsDevelopmentEnvironment yourself if DevelopmentOnly exception details should render in development.
Size limits
String fields in an HTTP report and rendered exception details default to a maximum of 16,384 characters. Configure smaller limits after registering the reporter:
using NT.Blazor.ErrorBoundary.Services;
builder.Services.Configure<NTBlazorErrorBoundaryHttpClientOptions>(options => {
options.MaxReportFieldLength = 4_096;
});
builder.Services.Configure<NTErrorBoundaryOptions>(options => {
options.MaxExceptionDetailsLength = 4_096;
});
Configure MaxReportFieldLength in both the client and server DI containers when using WebAssembly. The client truncates before sending, and the server truncates again before logging. A limit less than or equal to zero disables truncation.
Logging and telemetry
The package writes through ILogger and publishes OpenTelemetry metrics and traces through System.Diagnostics; the consuming application decides where they go. Log fields use OpenTelemetry semantic-convention names where a convention exists, and the blazor.* namespace otherwise.
OpenTelemetry host setup
Configure OpenTelemetry in the consuming ASP.NET Core host as usual. AddNTBlazorErrorBoundaryServerLogging adds this package's meter (MeterName) and activity source (ActivitySourceName) to whatever meter and tracer providers the host builds, so no package-specific OpenTelemetry call is needed; without an OpenTelemetry pipeline, nothing is collected.
dotnet add package OpenTelemetry.Extensions.Hosting
dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol
dotnet add package OpenTelemetry.Instrumentation.AspNetCore
using NT.Blazor.ErrorBoundary.AspNetCore;
using OpenTelemetry;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
builder.Services.AddNTBlazorErrorBoundaryServerLogging("/api/blazor-errors");
builder.Services.AddOpenTelemetry()
.ConfigureResource(resource => resource.AddService(builder.Environment.ApplicationName))
.WithLogging()
.WithMetrics()
.WithTracing(tracing => tracing.AddAspNetCoreInstrumentation())
.UseOtlpExporter();
var app = builder.Build();
app.MapNTBlazorErrorBoundaryTelemetry();
Set OTEL_EXPORTER_OTLP_ENDPOINT to your collector endpoint. The report URI (/api/blazor-errors) is the application's own endpoint for the package's JSON reports, not an OTLP collector endpoint.
Fields travel as attributes on each log entry, not in logging scopes, so IncludeScopes is not required. If the host already configures OpenTelemetry, for example through shared service defaults, keep that pipeline; make sure it enables logging, metrics, and tracing, and that filters allow Error logs from the NT.Blazor.ErrorBoundary categories.
Blazor's built-in telemetry
ASP.NET Core 10 publishes its own Blazor telemetry, which complements this package's: the Microsoft.AspNetCore.Components and Microsoft.AspNetCore.Components.Server.Circuits meters (navigation, event handling, and active, connected, and total circuit duration) and the Microsoft.AspNetCore.Components activity source (circuit start, navigation, and event handling). They are not enabled automatically, because event-handling traces add a span per UI event. Opt in where that volume is acceptable:
builder.Services.AddOpenTelemetry()
.WithMetrics(metrics => metrics.AddMeter("Microsoft.AspNetCore.Components", "Microsoft.AspNetCore.Components.Server.Circuits"))
.WithTracing(tracing => tracing.AddSource("Microsoft.AspNetCore.Components"));
Log fields
Server-rendered exceptions log the original Exception at Error with these attributes:
| Attribute | Value |
|---|---|
blazor.boundary.name |
The boundary's Name. |
blazor.error.fingerprint |
Grouping key, described below. |
blazor.error.reference_id |
The reference shown in the fallback UI. |
blazor.interactive |
Whether the boundary rendered interactively. |
blazor.render_mode |
The renderer name. |
url.full |
The current page URL. |
blazor.navigation.origin_url |
The page URL when the boundary was created. |
aspnetcore.components.circuit.id |
The circuit ID, for Blazor Server circuits. This is ASP.NET Core's own attribute name. |
blazor.app.version |
The version of the side that raised the error, described below. |
Reports received from the browser add:
| Attribute | Value |
|---|---|
blazor.report.kind |
Exception, JavaScriptError, JavaScriptUnhandledRejection, ResourceLoadFailed, NavigationStalled, or ReconnectFailed. |
blazor.exception.type, blazor.exception.message, blazor.exception.stacktrace, blazor.exception.details |
The original exception values. |
blazor.error.occurred_at |
When the error occurred in the browser; queued reports arrive later. |
blazor.app.version |
The version of the side that raised the error, described below. |
blazor.client.online |
The browser's online state. |
blazor.navigation.id, blazor.navigation.phase, blazor.navigation.intercepted, blazor.navigation.target_url, blazor.navigation.breadcrumbs |
Navigation context; breadcrumbs are a JSON array. |
blazor.page.traceparent |
The traceparent of the request that rendered the page. |
code.file.path, code.line.number, code.column.number |
Source location of a JavaScript error. |
user_agent.original |
The upload request's User-Agent header. |
session.id and microsoft.session.id |
The browser session identifier. |
user.id and enduser.id |
The ClaimTypes.NameIdentifier or sub claim, when the upload is authenticated. |
blazor.app.version is the version of the code that raised the error, so a client and server versioned separately each report their own:
- Server-rendered errors use the server app's version.
- WebAssembly errors use the WebAssembly app's version, read inside the browser.
- Reports the browser script raises use the server app's version, since the server renders the page and script.
Each version is read from that app's entry assembly: its informational version, which the .NET SDK sets to the project's <Version> and the Git commit it was built from, such as 1.4.0+3f2a9c1…. Set <Version> in each project to version them separately. A build without Git history gets the project version alone, and a project that sets IncludeSourceRevisionInInformationalVersion to false gets it without the commit.
The session and user values are written under two names because the Azure Monitor exporter reads only microsoft.session.id and enduser.id, while OpenTelemetry's conventions use session.id and user.id. The URL fields (url.full, blazor.navigation.origin_url, blazor.navigation.target_url, breadcrumbs, and code.file.path) are sent and logged without query strings or fragments; the server removes them from server-rendered errors, and the browser script and HTTP reporter remove them before sending. The endpoint removes them from every browser report it receives as well, before applying FilterReport and logging. Exception messages and stack traces are logged as reported and can contain full URLs, for example a failed request's URL with an access token in its query string. Scrub them with FilterReport if that matters for your app. String fields are truncated to MaxReportFieldLength.
JavaScriptError, JavaScriptUnhandledRejection, ResourceLoadFailed, and WebAssembly Exception reports are logged at Error with an exception. Browser exceptions are logged as ClientBlazorErrorReportException, whose Message, StackTrace, and ToString() return the original values; exporters that read those members, including OTLP's exception.message and exception.stacktrace, carry the original data, while exception.type is the wrapper's name and the original type is in blazor.exception.type.
NavigationStalled and ReconnectFailed describe a condition rather than a thrown error, so they are logged at Error without an exception, as events. Blazor Server circuit connection changes are logged the same way, at Warning (connection down) or Information (connection up), with aspnetcore.components.circuit.id. Each event's EventId name, which OpenTelemetry exporters send as the log's event name, is also written to microsoft.custom_event.name, which Azure Monitor turns into a customEvents row:
| Event name | Logged for |
|---|---|
blazor.navigation.stalled |
A NavigationStalled report. |
blazor.reconnect.failed |
A ReconnectFailed report. |
blazor.circuit.connection_down, blazor.circuit.connection_up |
A circuit's connection dropping or returning. |
blazor.error.fingerprint is a 16-character hexadecimal key for grouping occurrences of the same error. It hashes the report kind, the exception type, and the top five stack frames after removing file paths, line and column numbers, URL origins, query strings, and native offsets, so it stays the same across hosts and cache-busting URLs. It also stays the same across builds: content hashes in bundled file names (such as blazor.web.xmryko9e6j.js) and the numbers the C# compiler gives async state machines, lambdas, closures, and local functions (such as <Load>d__5 or <>c__DisplayClass0_0) are removed, because they change whenever unrelated code does. When a stack has no frames, the exception message is hashed instead.
The HTTP reporter treats network and non-success response failures as reporting failures, logs a warning, and does not rethrow them into the component tree. Cancellation requested by the caller is preserved.
Metrics
The server package records the counter blazor.errors (unit {error}) on the meter NT.Blazor.ErrorBoundary (NTBlazorErrorBoundaryAspNetCoreExtensions.MeterName), once per logged report. Its attributes are blazor.error.source (server or client), blazor.report.kind, and, for server-rendered errors only, blazor.boundary.name. Client reports are never tagged with a boundary name, because browser-supplied values would allow unbounded attribute cardinality. Reports that are rejected or dropped by a filter are not counted.
Trace correlation
- Server-rendered errors are logged inside the current
Activity, if any; the library does not start one for them. - Browser reports sent with
fetchorHttpClientcarry the page'straceparentas a header, so ASP.NET Core instrumentation makes the upload part of the page request's trace. Cross-origin endpoints must allow thetraceparentheader through CORS. - Beacon uploads, sent as the page closes, can't set headers. When an upload is outside the page's trace, the endpoint logs the report under a
blazor.client_reportactivity parented toblazor.page.traceparent. When the host enables tracing, that span is exported inside the page's trace; otherwise the log still carries the page's trace ID. - A successful upload returns HTTP 204 even though its log describes an error. The library does not mark the upload span as failed.
The integration tests use the real OpenTelemetry SDK with in-memory exporters to verify field export without scopes, exception data, trace correlation, and that the report span and counter reach a host pipeline with no package-specific registration.
Sending errors to another backend
To deliver errors somewhere directly as well as logging them, register one INTBlazorErrorBoundaryExporter singleton in the server project. The package calls ExportException for every server-rendered exception and accepted browser exception report, and ExportEvent for every event in the event table above. Each call carries the same attributes that are logged, after FilterReport and truncation. The calls run on the reporting thread, so queue the work and send it in the background. If an exporter throws, a warning is logged and the error is still logged and answered normally. Only the last registered exporter is used. NT.Blazor.ErrorBoundary.AzureMonitor is an exporter. To replace logging rather than add to it, see Custom reporters.
Azure Monitor and Application Insights
Use the Azure Monitor OpenTelemetry distro for the host's telemetry, and add NT.Blazor.ErrorBoundary.AzureMonitor so this package's errors and events reach Application Insights in full:
dotnet add package Azure.Monitor.OpenTelemetry.AspNetCore
dotnet add package NT.Blazor.ErrorBoundary.AzureMonitor
using Azure.Monitor.OpenTelemetry.AspNetCore;
using NT.Blazor.ErrorBoundary.AspNetCore;
using NT.Blazor.ErrorBoundary.AzureMonitor;
builder.Services.AddNTBlazorErrorBoundaryServerLogging("/api/blazor-errors");
builder.Services.AddNTBlazorErrorBoundaryAzureMonitor();
builder.Services.AddOpenTelemetry().UseAzureMonitor();
Set APPLICATIONINSIGHTS_CONNECTION_STRING to the resource's connection string; both read it. When that setting is present, the sample app enables this registration and Blazor's built-in telemetry.
Why the add-on
Through the distro alone, two things go wrong, both verified against a live resource:
- Browser exceptions cannot be grouped. The Azure Monitor exporter builds an exception's type, stack, and problem ID from the thrown .NET object. A browser error arrives as text, so it is logged as
ClientBlazorErrorReportException: every browser error shares one problem ID and has no frames in the Failures view. - Errors and events are sampled away. The distro samples traces and, with
EnableTraceBasedLogsSampleron (its default), drops every log inside a sampled-out trace. Server-rendered exceptions, browser reports, and events disappeared this way.
The add-on sends every error and event this package reports directly to Application Insights instead:
| Signal | Table | Notes |
|---|---|---|
| Server-rendered exception | exceptions |
Type, parsed stack, and a type at method problem ID; the full exception text, including inner exceptions, is in blazor.exception.details. |
| Browser or WebAssembly exception | exceptions |
The original type, parsed frames (.NET, Mono, Chrome, Firefox, and Safari formats), and a type at method problem ID: the same form Application Insights computes for exceptions the JavaScript SDK sends, so the Failures view groups them by where they were thrown. |
| Stalled navigation, failed reconnection, circuit connection down and up | customEvents |
Named as in the event table above. |
blazor.errors |
customMetrics |
Through the distro, as usual. |
blazor.client_report spans |
dependencies |
Through the distro, only for beacon uploads, as described under trace correlation. |
- Not sampled. Direct delivery does not pass through the host's trace sampling, so no error or event is dropped by it. Each one still carries
operation_Id, the trace it happened in, for correlation. - Recorded once. The add-on keeps this package's log categories (
NT.Blazor.ErrorBoundary.ClientReportandNT.Blazor.ErrorBoundary.AspNetCore.*) out of the OpenTelemetry log pipeline, so nothing is duplicated inexceptions,customEvents, ortraces. Logging providers outside OpenTelemetry, such as the console, still receive them. If the host also exports OpenTelemetry logs to another backend, that backend no longer receives these entries. - Context. Browser reports fill
session_Id,user_AuthenticatedId(when the upload is authenticated), the user agent, andapplication_Version(fromblazor.app.version; server-rendered errors fill it too). Every other attribute, includingblazor.error.fingerprint, is a custom property incustomDimensions, whose values Application Insights truncates at 8,192 characters. Query dotted names with brackets, for examplecustomDimensions['blazor.report.kind']. - Delivery. Envelopes are queued on the reporting thread and posted to the connection string's
IngestionEndpoint(v2.1/track) by a background sender. Each attempt times out after 10 seconds. Timeouts, network failures,408,429, and5xxare retried twice, after theRetry-Afterthe response gives (up to a minute) or otherwise 2 and then 4 seconds; when a206reports some items rejected, only those rejected with one of those statuses are resent. Other failures are logged as warnings, with up to 1,024 characters of the response body. The queue holds 1,000 envelopes and about 32 MB of text, and stops taking events at 800 so a burst of circuit events cannot crowd out exceptions; when it drops anything, one warning is logged until it has room again. Shutdown drains the queue, and a warning reports how many items were left if the host's shutdown timeout cuts it short. An exporter that throws is logged as a warning and never fails the report request. Uploads run with OpenTelemetry instrumentation suppressed and withoutHttpClientrequest logging, so they add no dependency or trace rows of their own. - Configuration.
NTBlazorAzureMonitorOptions.ConnectionStringdefaults toAPPLICATIONINSIGHTS_CONNECTION_STRING, as the distro does.CloudRoleNamedefaults toOTEL_SERVICE_NAME, thenunknown_service:<process name>, matching the distro so these rows sit under the host's role. SetCredentialto aTokenCredentialwhen the resource requires Microsoft Entra authentication. With a credential, the connection string'sIngestionEndpointmust usehttps, so the token is never sent in clear text; the exporter throwsInvalidOperationExceptionotherwise.
using Azure.Identity;
builder.Services.AddNTBlazorErrorBoundaryAzureMonitor(options => {
options.CloudRoleName = "storefront";
options.Credential = new DefaultAzureCredential();
});
DefaultAzureCredential comes from the Azure.Identity package, which the add-on does not reference.
Without the add-on, set UseAzureMonitor(options => options.EnableTraceBasedLogsSampler = false) so the distro does not drop this package's logs, and group browser exceptions by customDimensions['blazor.error.fingerprint'] rather than by problem ID.
Workbook and alerts
docs/azure-monitor contains a workbook and alert rules built on these fields:
blazor-errors.workbook.jsonlists errors grouped by fingerprint with occurrence, user, and session counts and the app version each was first and last seen in, so a regression shows which release introduced it and a fix shows whether it stopped; errors first seen in the last day, with their version; error trends by source; and Blazor events. The version isblazor.app.version, falling back to Application Insights'application_Version. Import it from Workbooks > New > Advanced Editor > Gallery Template on the Application Insights resource.blazor-error-alerts.bicepcreates two log search alerts: one fires when a single error fingerprint exceeds a threshold within 15 minutes, and the other fires on stalled navigations or failed reconnections. Deploy it withaz deployment group create --resource-group <group> --template-file docs/azure-monitor/blazor-error-alerts.bicep --parameters applicationInsightsId=<resource-id> actionGroupId=<action-group-id>.
A test runs the real Azure Monitor exporter against a captured transport and asserts the envelopes it would send for server exceptions, browser exceptions, events, and context fields.
Securing the telemetry endpoint
The package intentionally does not choose authorization, CORS, rate-limiting, or telemetry-retention policy for the host. The mapped endpoint accepts exception messages and stack traces, so treat it as diagnostic ingestion rather than a general public API.
MapNTBlazorErrorBoundaryTelemetry returns a RouteHandlerBuilder, allowing normal ASP.NET Core endpoint policy:
app.MapNTBlazorErrorBoundaryTelemetry()
.RequireAuthorization("BlazorTelemetry")
.RequireRateLimiting("blazor-telemetry");
The endpoint applies these limits itself:
- Request bodies over
NTBlazorErrorBoundaryHttpClientOptions.MaxReportRequestBytes(default 1 MiB) are rejected with413. - Reports with an unknown
ReportKind, or anOccurredAtUtcmore than 5 minutes in the future or older than 7 days, are rejected with400. Register aTimeProviderin DI to control the clock in tests. - URL fields (
Uri,OriginUri,TargetUri,JavaScriptSource, and breadcrumb URIs) are stripped of query strings and fragments beforeFilterReportand logging. - String fields are truncated to
MaxReportFieldLength.
Use FilterReport to redact or drop reports. The client applies it before sending, and the server applies it before logging browser reports and server-rendered errors. Return a modified copy to redact, or null to drop:
builder.Services.Configure<NTBlazorErrorBoundaryHttpClientOptions>(options => {
options.FilterReport = report => report.ExceptionType == "MyApp.ExpectedException"
? null
: report;
});
NTBlazorErrorReport is a record, so with makes a redacted copy. This example masks email addresses in the free-text fields:
var email = new Regex(@"[\w.+-]+@[\w-]+\.[\w.-]+", RegexOptions.Compiled);
string? Mask(string? text) => text is null ? null : email.Replace(text, "[email]");
builder.Services.Configure<NTBlazorErrorBoundaryHttpClientOptions>(options => {
options.FilterReport = report => report with {
ExceptionMessage = Mask(report.ExceptionMessage),
ExceptionDetails = Mask(report.ExceptionDetails),
ExceptionStackTrace = Mask(report.ExceptionStackTrace)
};
});
Configure the same filter on the client and the server: the client copy keeps the data off the network, and the server copy covers browser reports, which do not pass through the client filter. A report's ToString() prints only its kind, exception type, and reference ID, so a report written to a log by accident does not carry these fields.
For server-rendered errors, the filter controls whether the error is logged and the fields logged with it, but the original Exception object is still logged unchanged; apply message redaction for it in the logging provider.
If the filter throws, the report is dropped rather than sent or logged unfiltered, and a warning with the filter's exception is logged instead. The endpoint still answers 204, so browsers do not retry the report.
Choose policies that match the application:
- Require authorization when browser reports are sent with an authenticated identity.
- Configure the client reporter to attach the corresponding cookie or bearer token.
- Apply rate limits to prevent telemetry abuse.
- Configure CORS explicitly for cross-origin WebAssembly applications.
- Treat logged URIs, exception messages, and stack traces as potentially sensitive data.
- Apply redaction and retention in the configured logging provider.
Data flow
Server-rendered exception:
NTErrorBoundary
-> INTBlazorErrorReporter
-> NTBlazorServerErrorReporter
-> ILogger
WebAssembly exception:
NTErrorBoundary (or an unhandled exception outside any boundary)
-> NTHttpClientBlazorErrorReporter
-> POST /api/blazor-errors (HttpClient; on retryable failure, the browser retry queue)
-> MapNTBlazorErrorBoundaryTelemetry
-> ILogger
Browser-detected problem (JavaScript error, stalled navigation, failed framework load, failed reconnection):
nt-blazor-error-boundary.js
-> POST /api/blazor-errors (fetch; on retryable failure, the browser retry queue)
-> MapNTBlazorErrorBoundaryTelemetry
-> ILogger
On the server, each ILogger step also passes the error to the registered INTBlazorErrorBoundaryExporter, if there is one.
Detect stalled interactive navigation
Stall detection is opt-in for navigation that must reach an interactive Blazor render. Place NTBlazorInteractiveReady in the destination's interactive component tree:
@page "/claims/recovery/{ClaimId:int}"
@rendermode InteractiveAuto
<NTBlazorInteractiveReady />
<RecoveryContent />
Mark links whose telemetry should wait for that signal:
<a href="@($"/claims/recovery/{claimId}")"
data-nt-require-interactive-ready="true">
Recovery Management
</a>
data-nt-require-interactive-ready="true" affects telemetry only. It does not change routing, cancel navigation, delay rendering, or enable interactivity.
- Without the attribute, the navigation is recorded as breadcrumbs only, and no stall report is scheduled.
- With the attribute, telemetry waits until
NTBlazorInteractiveReadycompletes its first interactive render. - If the marker doesn't report before
data-stall-timeout-ms, the browser submits aNavigationStalledreport with the last recorded navigation phase.
NTBlazorInteractiveReady deliberately has no render mode and renders no HTML. It inherits the renderer used by its containing page or component. OnAfterRenderAsync doesn't execute during prerendering, and the marker reports readiness only when RendererInfo.IsInteractive is true.
Only use the link attribute when the destination contains the marker beneath an InteractiveServer, InteractiveWebAssembly, or InteractiveAuto boundary. A marker in a static SSR tree can't report interactive readiness. The marker signals once per component instance, so parameter-only navigation that reuses the same instance requires a destination-specific readiness strategy.
Browser telemetry data
Browser reports can include:
- Application version and browser session identifier.
- Boundary name, report kind, exception type, message, details, and stack trace.
- Current, origin, and target URIs with query strings and fragments removed. Exception messages and stack traces are sent as they are and can contain URLs with query strings.
- Navigation identifier, phase, interception state, and recent breadcrumbs.
- Renderer name and interactive state.
- JavaScript source, line, and column for browser errors.
- Browser online state.
String fields are truncated before logging according to NTBlazorErrorBoundaryHttpClientOptions.MaxReportFieldLength.
TypeScript static asset
The browser source of truth is NT.Blazor.ErrorBoundary/wwwroot/nt-blazor-error-boundary.ts. Don't edit the generated JavaScript directly.
npm ci
npm run check
npm run build
npm test
npm test runs the release-tooling tests and the browser-script tests in Tests/ClientAssets, which load the built nt-blazor-error-boundary.js in a sandbox with fake browser APIs.
Building NT.Blazor.ErrorBoundary automatically restores the locked npm dependencies when necessary, compiles the TypeScript, and minifies the result. The generated nt-blazor-error-boundary.js is packed and published as the static web asset. The TypeScript source is neither packed nor published.
Development
The repository uses the SDK selected by global.json and builds every target framework.
dotnet restore ./NT.Blazor.ErrorBoundary.slnx
dotnet build ./NT.Blazor.ErrorBoundary.slnx --configuration Release --no-restore
dotnet test --solution ./NT.Blazor.ErrorBoundary.slnx --configuration Release --no-build --no-restore
Tests use xUnit v3 on Microsoft.Testing.Platform v2. The .NET SDK selects Microsoft.Testing.Platform through global.json; the test projects do not depend on VSTest, Microsoft.NET.Test.Sdk, or Coverlet.
samples/ contains a small Blazor Web App (server and WebAssembly client) wired exactly as this README describes, with pages that fail under static SSR, Interactive Server, and Interactive WebAssembly. Tests/NT.Blazor.ErrorBoundary.EndToEnd.Tests runs it on Kestrel and drives it with Playwright's Chromium to verify the fallback, reference IDs in server logs, recovery, unhandled WebAssembly exceptions, JavaScript errors, stall detection, and the scoped styles. Install the browser once after building:
pwsh ./Tests/NT.Blazor.ErrorBoundary.EndToEnd.Tests/bin/Debug/net11.0/playwright.ps1 install chromium
Without the browser, the end-to-end tests are skipped. Set NT_E2E_REQUIRED=true to make them fail instead, as the Build and Pack workflow does.
Generate Cobertura coverage with Microsoft's testing-platform coverage extension:
dotnet test --project ./Tests/NT.Blazor.ErrorBoundary.Tests/NT.Blazor.ErrorBoundary.Tests.csproj --framework net10.0 --configuration Release --no-build --no-restore --results-directory ./artifacts/coverage/core --coverage --coverage-output-format cobertura --coverage-output coverage.cobertura.xml
dotnet test --project ./Tests/NT.Blazor.ErrorBoundary.AspNetCore.Tests/NT.Blazor.ErrorBoundary.AspNetCore.Tests.csproj --framework net10.0 --configuration Release --no-build --no-restore --results-directory ./artifacts/coverage/aspnetcore --coverage --coverage-output-format cobertura --coverage-output coverage.cobertura.xml
dotnet test --project ./Tests/NT.Blazor.ErrorBoundary.AzureMonitor.Tests/NT.Blazor.ErrorBoundary.AzureMonitor.Tests.csproj --framework net10.0 --configuration Release --no-build --no-restore --results-directory ./artifacts/coverage/azuremonitor --coverage --coverage-output-format cobertura --coverage-output coverage.cobertura.xml
The full suite runs on every target framework. Coverage runs once against .NET 10 for each test project so parallel target frameworks cannot overwrite a shared output file. The Build and Pack workflow uploads the reports as the code-coverage artifact.
Warnings are treated as errors across the repository. Packable projects generate XML documentation, so missing or invalid public API documentation also fails the build.
The library build also runs the TypeScript compilation and minification pipeline. Run npm run check separately for a no-emit TypeScript validation.
Create local packages with:
dotnet pack ./NT.Blazor.ErrorBoundary/NT.Blazor.ErrorBoundary.csproj --configuration Release --no-build --output ./artifacts/packages
dotnet pack ./NT.Blazor.ErrorBoundary.AspNetCore/NT.Blazor.ErrorBoundary.AspNetCore.csproj --configuration Release --no-build --output ./artifacts/packages
dotnet pack ./NT.Blazor.ErrorBoundary.AzureMonitor/NT.Blazor.ErrorBoundary.AzureMonitor.csproj --configuration Release --no-build --output ./artifacts/packages
CI and releases
The Build and Pack workflow runs for pull requests and manual validation. It builds, tests, creates the NuGet packages and symbol packages, and uploads them as workflow artifacts.
Publication follows the same preview and stable semantic-release model as NTComponents.
- On NuGet.org, add a trusted publishing policy for
publish-prerelease.ymland another forrelease.yml, then add the NuGet.org profile name (not the email) that owns them as theNUGET_USERGitHub Actions secret. Each policy's package scope must cover all three package IDs, for example with the globNT.Blazor.ErrorBoundary*, and must allow publishing new packages, becauseNT.Blazor.ErrorBoundary.AzureMonitorhas never been published. When the packages belong to an organization,NUGET_USERis the profile name of a member of that organization. Both workflows publish and unlist throughNuGet/login, so no NuGet API key is stored. - Merge release-worthy Conventional Commits into
main. Publish Prereleasebuilds and tests the repository automatically.- Semantic-release updates the
previewbranch and creates avX.Y.Z-preview.Ntag and GitHub prerelease. - The same workflow packs all three packages with that preview version and publishes them and their symbols to NuGet.org.
- When the preview is ready, run the manual
Releaseworkflow from GitHub Actions. - The release workflow builds and tests again, creates the stable
vX.Y.Ztag and GitHub release, and publishes all three stable packages. - After stable publication succeeds, the workflow unlists prerelease versions whose base version is at or below the stable release.
Release calculation follows Conventional Commits:
fix:creates a patch release.feat:creates a minor release.BREAKING CHANGE:creates a major release.- Documentation, CI, and chore-only changes do not create a release by default.
Do not create release tags manually. If a push to main contains no release-worthy commits, semantic-release creates no preview tag and prerelease publication is skipped. If the manual stable release has no release-worthy commits, the Release run fails at "Resolve stable package version" with "No stable release tag found on this commit", and nothing is published.
License
MIT. See LICENSE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. net11.0 is compatible. |
-
net10.0
- NT.Blazor.ErrorBoundary (>= 2.0.0)
- OpenTelemetry.Api.ProviderBuilderExtensions (>= 1.15.3)
-
net11.0
- NT.Blazor.ErrorBoundary (>= 2.0.0)
- OpenTelemetry.Api.ProviderBuilderExtensions (>= 1.15.3)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on NT.Blazor.ErrorBoundary.AspNetCore:
| Package | Downloads |
|---|---|
|
NT.Blazor.ErrorBoundary.AzureMonitor
Sends every NT.Blazor.ErrorBoundary error and event to Azure Monitor Application Insights directly, unaffected by trace sampling: server and browser exceptions as native exceptions with their original type and parsed stack, and navigation, reconnection, and circuit events as custom events. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.0.0 | 45 | 11/11/2026 |
| 2.0.0-preview.1 | 40 | 11/11/2026 |
| 1.2.0 | 349 | 9/11/2026 |
| 1.1.0 | 2,183 | 8/4/2026 |
| 1.0.0 | 1,372 | 7/22/2026 |