You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: aspnetcore/blazor/fundamentals/handle-errors.md
+52-48Lines changed: 52 additions & 48 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -206,10 +206,10 @@ The framework terminates a circuit when an unhandled exception occurs for the fo
206
206
207
207
:::moniker range=">= aspnetcore-6.0"
208
208
209
-
For global exception handling, see the following sections:
209
+
For approaches to handling exceptions globally, see the following sections:
210
210
211
-
*[Error boundaries](#error-boundaries)
212
-
*[Alternative global exception handling](#alternative-global-exception-handling)
211
+
*[Error boundaries](#error-boundaries): Applies to all Blazor apps.
212
+
*[Alternative global exception handling](#alternative-global-exception-handling): Applies to Blazor Server, Blazor WebAssembly, and Blazor Web Apps (8.0 or later) that adopt a global interactive render mode.
213
213
214
214
## Error boundaries
215
215
@@ -331,14 +331,24 @@ To avoid the infinite loop where recovering merely rerenders a component that th
331
331
332
332
## Alternative global exception handling
333
333
334
+
:::moniker-end
335
+
336
+
:::moniker range=">= aspnetcore-8.0"
337
+
338
+
The approach described in this section applies to Blazor Server, Blazor WebAssembly, and Blazor Web Apps that adopt a global interactive render mode (`InteractiveServer`, `InteractiveWebAssembly`, or `InteractiveAuto`). The approach doesn't work with Blazor Web Apps that adopt per-page/component render modes or static server-side rendering (static SSR) because the approach relies on a [`CascadingValue`](xref:blazor/components/cascading-values-and-parameters#cascadingvalue-component)/[`CascadingParameter`](xref:blazor/components/cascading-values-and-parameters#cascadingparameter-attribute), which don't work across render mode boundaries or with components that adopt static SSR.
339
+
340
+
:::moniker-end
341
+
342
+
:::moniker range=">= aspnetcore-6.0"
343
+
334
344
An alternative to using [Error boundaries](#error-boundaries) (<xref:Microsoft.AspNetCore.Components.Web.ErrorBoundary>) is to pass a custom error component as a [`CascadingValue`](xref:blazor/components/cascading-values-and-parameters#cascadingvalue-component) to child components. An advantage of using a component over using an [injected service](xref:blazor/fundamentals/dependency-injection) or a custom logger implementation is that a cascaded component can render content and apply CSS styles when an error occurs.
335
345
336
-
The following `Error` component example merely logs errors, but methods of the component can process errors in any way required by the app, including through the use of multiple error processing methods.
346
+
The following `ProcessError` component example merely logs errors, but methods of the component can process errors in any way required by the app, including through the use of multiple error processing methods.
337
347
338
-
`Error.razor`:
348
+
`ProcessError.razor`:
339
349
340
350
```razor
341
-
@inject ILogger<Error> Logger
351
+
@inject ILogger<ProcessError> Logger
342
352
343
353
<CascadingValue Value="this">
344
354
@ChildContent
@@ -348,13 +358,13 @@ The following `Error` component example merely logs errors, but methods of the c
// Call StateHasChanged if ProcessError directly participates in
357
-
// rendering. If ProcessError only logs or records the error,
366
+
// Call StateHasChanged if LogError directly participates in
367
+
// rendering. If LogError only logs or records the error,
358
368
// there's no need to call StateHasChanged.
359
369
//StateHasChanged();
360
370
}
@@ -368,55 +378,51 @@ The following `Error` component example merely logs errors, but methods of the c
368
378
369
379
:::moniker range=">= aspnetcore-8.0"
370
380
371
-
In the `Routes` component, wrap the <xref:Microsoft.AspNetCore.Components.Routing.Router> component (`<Router>...</Router>`) with the `Error` component. This permits the `Error` component to cascade down to any component of the app where the `Error` component is received as a [`CascadingParameter`](xref:blazor/components/cascading-values-and-parameters#cascadingparameter-attribute).
381
+
When using this approach in a Blazor Web App, open the `Routes` component and wrap the <xref:Microsoft.AspNetCore.Components.Routing.Router> component (`<Router>...</Router>`) with the `ProcessError` component. This permits the `ProcessError` component to cascade down to any component of the app where the `ProcessError` component is received as a [`CascadingParameter`](xref:blazor/components/cascading-values-and-parameters#cascadingparameter-attribute).
In the `App` component, wrap the <xref:Microsoft.AspNetCore.Components.Routing.Router> component (`<Router>...</Router>`) with the `Error` component. This permits the `Error` component to cascade down to any component of the app where the `Error` component is received as a [`CascadingParameter`](xref:blazor/components/cascading-values-and-parameters#cascadingparameter-attribute).
397
+
When using this approach in a Blazor Server or Blazor WebAssembly app, open the `App` component, wrap the <xref:Microsoft.AspNetCore.Components.Routing.Router> component (`<Router>...</Router>`) with the `ProcessError` component. This permits the `ProcessError` component to cascade down to any component of the app where the `ProcessError` component is received as a [`CascadingParameter`](xref:blazor/components/cascading-values-and-parameters#cascadingparameter-attribute).
388
398
389
399
In `App.razor`:
390
400
391
401
```razor
392
-
<Error>
402
+
<ProcessError>
393
403
<Router ...>
394
404
...
395
405
</Router>
396
-
</Error>
406
+
</ProcessError>
397
407
```
398
408
399
-
:::moniker-end
400
-
401
-
:::moniker range=">= aspnetcore-6.0"
402
-
403
409
To process errors in a component:
404
410
405
-
* Designate the `Error` component as a [`CascadingParameter`](xref:blazor/components/cascading-values-and-parameters#cascadingparameter-attribute) in the [`@code`](xref:mvc/views/razor#code) block. In an example `Counter` component in an app based on a Blazor project template, add the following `Error` property:
411
+
* Designate the `ProcessError` component as a [`CascadingParameter`](xref:blazor/components/cascading-values-and-parameters#cascadingparameter-attribute) in the [`@code`](xref:mvc/views/razor#code) block. In an example `Counter` component in an app based on a Blazor project template, add the following `ProcessError` property:
406
412
407
413
```csharp
408
414
[CascadingParameter]
409
-
publicError?Error { get; set; }
415
+
publicProcessError?ProcessError { get; set; }
410
416
```
411
417
412
-
* Call an error processing method in any `catch` block with an appropriate exception type. The example `Error` component only offers a single `ProcessError` method, but the error processing component can provide any number of error processing methods to address alternative error processing requirements throughout the app. In the following `Counter` component example, an exception is thrown and trapped when the count is greater than five:
418
+
* Call an error processing method in any `catch` block with an appropriate exception type. The example `ProcessError` component only offers a single `LogError` method, but the error processing component can provide any number of error processing methods to address alternative error processing requirements throughout the app. The following `Counter` component `@code` block example includes the `ProcessError` cascading parameter and traps an exception for logging when the count is greater than five:
413
419
414
420
```razor
415
421
@code {
416
422
private int currentCount = 0;
417
423
418
424
[CascadingParameter]
419
-
public Error? Error { get; set; }
425
+
public ProcessError? ProcessError { get; set; }
420
426
421
427
private void IncrementCount()
422
428
{
@@ -431,20 +437,18 @@ To process errors in a component:
431
437
}
432
438
catch (Exception ex)
433
439
{
434
-
Error?.ProcessError(ex);
440
+
ProcessError?.LogError(ex);
435
441
}
436
442
}
437
443
}
438
444
```
439
445
440
-
Using the preceding `Error` component with the preceding changes made to a `Counter` component, the browser's developer tools console indicates the trapped, logged error:
446
+
The logged error:
441
447
442
-
```console
443
-
fail: {COMPONENT NAMESPACE}.Error[0]
444
-
Error:ProcessError - Type: System.InvalidOperationException Message: Current count is over five!
> :::no-loc text="ProcessError.LogError: System.InvalidOperationException Message: Current count is over five!":::
446
450
447
-
If the `ProcessError` method directly participates in rendering, such as showing a custom error message bar or changing the CSS styles of the rendered elements, call [`StateHasChanged`](xref:blazor/components/lifecycle#state-changes-statehaschanged) at the end of the `ProcessErrors` method to rerender the UI.
451
+
If the `LogError` method directly participates in rendering, such as showing a custom error message bar or changing the CSS styles of the rendered elements, call [`StateHasChanged`](xref:blazor/components/lifecycle#state-changes-statehaschanged) at the end of the `LogError` method to rerender the UI.
448
452
449
453
Because the approaches in this section handle errors with a [`try-catch`](/dotnet/csharp/language-reference/keywords/try-catch) statement, an app's SignalR connection between the client and server isn't broken when an error occurs and the circuit remains alive. Other unhandled exceptions remain fatal to a circuit. For more information, see the section on [how a circuit reacts to unhandled exceptions](#unhandled-exceptions-for-circuits).
450
454
@@ -454,13 +458,13 @@ Because the approaches in this section handle errors with a [`try-catch`](/dotne
454
458
455
459
An app can use an error processing component as a cascading value to process errors in a centralized way.
456
460
457
-
The following `Error` component passes itself as a [`CascadingValue`](xref:blazor/components/cascading-values-and-parameters#cascadingvalue-component) to child components. The following example merely logs the error, but methods of the component can process errors in any way required by the app, including through the use of multiple error processing methods. An advantage of using a component over using an [injected service](xref:blazor/fundamentals/dependency-injection) or a custom logger implementation is that a cascaded component can render content and apply CSS styles when an error occurs.
461
+
The following `ProcessError` component passes itself as a [`CascadingValue`](xref:blazor/components/cascading-values-and-parameters#cascadingvalue-component) to child components. The following example merely logs the error, but methods of the component can process errors in any way required by the app, including through the use of multiple error processing methods. An advantage of using a component over using an [injected service](xref:blazor/fundamentals/dependency-injection) or a custom logger implementation is that a cascaded component can render content and apply CSS styles when an error occurs.
458
462
459
-
`Error.razor`:
463
+
`ProcessError.razor`:
460
464
461
465
```razor
462
466
@using Microsoft.Extensions.Logging
463
-
@inject ILogger<Error> Logger
467
+
@inject ILogger<ProcessError> Logger
464
468
465
469
<CascadingValue Value="this">
466
470
@ChildContent
@@ -470,9 +474,9 @@ The following `Error` component passes itself as a [`CascadingValue`](xref:blazo
@@ -481,28 +485,28 @@ The following `Error` component passes itself as a [`CascadingValue`](xref:blazo
481
485
> [!NOTE]
482
486
> For more information on <xref:Microsoft.AspNetCore.Components.RenderFragment>, see <xref:blazor/components/index#child-content-render-fragments>.
483
487
484
-
In the `App` component, wrap the <xref:Microsoft.AspNetCore.Components.Routing.Router> component with the `Error` component. This permits the `Error` component to cascade down to any component of the app where the `Error` component is received as a [`CascadingParameter`](xref:blazor/components/cascading-values-and-parameters#cascadingparameter-attribute).
488
+
In the `App` component, wrap the <xref:Microsoft.AspNetCore.Components.Routing.Router> component with the `ProcessError` component. This permits the `ProcessError` component to cascade down to any component of the app where the `ProcessError` component is received as a [`CascadingParameter`](xref:blazor/components/cascading-values-and-parameters#cascadingparameter-attribute).
485
489
486
490
`App.razor`:
487
491
488
492
```razor
489
-
<Error>
493
+
<ProcessError>
490
494
<Router ...>
491
495
...
492
496
</Router>
493
-
</Error>
497
+
</ProcessError>
494
498
```
495
499
496
500
To process errors in a component:
497
501
498
-
* Designate the `Error` component as a [`CascadingParameter`](xref:blazor/components/cascading-values-and-parameters#cascadingparameter-attribute) in the [`@code`](xref:mvc/views/razor#code) block:
502
+
* Designate the `ProcessError` component as a [`CascadingParameter`](xref:blazor/components/cascading-values-and-parameters#cascadingparameter-attribute) in the [`@code`](xref:mvc/views/razor#code) block:
499
503
500
504
```razor
501
505
[CascadingParameter]
502
-
public Error Error { get; set; }
506
+
public ProcessError ProcessError { get; set; }
503
507
```
504
508
505
-
* Call an error processing method in any `catch` block with an appropriate exception type. The example `Error` component only offers a single `ProcessError` method, but the error processing component can provide any number of error processing methods to address alternative error processing requirements throughout the app.
509
+
* Call an error processing method in any `catch` block with an appropriate exception type. The example `ProcessError` component only offers a single `LogError` method, but the error processing component can provide any number of error processing methods to address alternative error processing requirements throughout the app.
506
510
507
511
```csharp
508
512
try
@@ -511,16 +515,16 @@ To process errors in a component:
511
515
}
512
516
catch (Exceptionex)
513
517
{
514
-
Error.ProcessError(ex);
518
+
ProcessError.LogError(ex);
515
519
}
516
520
```
517
521
518
-
Using the preceding example `Error` component and `ProcessError` method, the browser's developer tools console indicates the trapped, logged error:
522
+
Using the preceding example `ProcessError` component and `LogError` method, the browser's developer tools console indicates the trapped, logged error:
519
523
520
-
> fail: BlazorSample.Shared.Error[0]
521
-
> Error:ProcessError - Type: System.NullReferenceException Message: Object reference not set to an instance of an object.
> :::no-loc text="ProcessError.LogError: System.NullReferenceException Message: Object reference not set to an instance of an object.":::
522
526
523
-
If the `ProcessError` method directly participates in rendering, such as showing a custom error message bar or changing the CSS styles of the rendered elements, call [`StateHasChanged`](xref:blazor/components/lifecycle#state-changes-statehaschanged) at the end of the `ProcessErrors` method to rerender the UI.
527
+
If the `LogError` method directly participates in rendering, such as showing a custom error message bar or changing the CSS styles of the rendered elements, call [`StateHasChanged`](xref:blazor/components/lifecycle#state-changes-statehaschanged) at the end of the `LogError` method to rerender the UI.
524
528
525
529
Because the approaches in this section handle errors with a [`try-catch`](/dotnet/csharp/language-reference/keywords/try-catch) statement, a Blazor app's SignalR connection between the client and server isn't broken when an error occurs and the circuit remains alive. Any unhandled exception is fatal to a circuit. For more information, see the section on [how a circuit reacts to unhandled exceptions](#unhandled-exceptions-for-circuits).
0 commit comments